Stop code execution until button is pressed - java

After choose.setVisible(true) I would like first
to be able to choose and after pressing the ok button
to continue execution.
The below code shows the chooser and continues
without waiting.
static class box extends JFrame {
Checkbox cboxtps = new Checkbox("Grf1", false);
Checkbox cboxrspt = new Checkbox("Grf2", false);
JLabel lblQts = new JLabel("Please select graphs");
JButton btn1 = new JButton("Go");
public box(String str) {
super(str);
setLayout(new GridLayout(4, 1));
add(lblQts);
add(cboxtps);
add(cboxrspt);
add(btn1);
btn1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
//Execute when button is pressed
System.out.println("You clicked the button");
}
});
}
}
public static void main(String args[]) {
box choose = new box("Select Graphs");
choose.setSize(300, 150);
choose.pack();
choose.setVisible(true);
List<File> filepaths = fileselect();
list = Splitter(filepaths);
}

Since you are working asynchronously here, you would have to put the code after choose.setVisible(true) into the actionPerformed callback like so:
public void actionPerformed(ActionEvent e)
{
System.out.println("You clicked the button");
List<File> filepaths = fileselect();
list = Splitter(filepaths);
}
In general, when working with a lot of callbacks it is the best to define helper functions to avoid deep nesting.

Related

Combobox doesn't show ArrayList on Java GUI

I'm new to swing, and I'm trying to show an Array data on a ComboBox, but for some reason whenever I add data to it, the ComboBox doesn't seem to refresh with the data inserted, even though if I run a test on console using a system.out inside the forEach, the data inserted on the ArrayList (it also shows on debug). Here's the mainMenu class:
package com.gui.main;
/* imports */
public class mainMenu {
ArrayList<Instituicao> instituicoes = new ArrayList<Instituicao>();
private JFrame frame;
public static void main(String[] args) {
/*...*/
}
public mainMenu() {
initialize();
}
public void setComboboxInstituicao(JComboBox comboBox) {
comboBox.removeAllItems();
Vector<String> inst = new Vector<String>();
if(!instituicoes.isEmpty()) {
for(Instituicao i : instituicoes) {
inst.add(i.getNomeInstituicao());
}
} else {
inst.add("Select...");
}
comboBox.setModel(new DefaultComboBoxModel<String>(inst));
comboBox.setBounds(22, 120, 600, 33);
frame.getContentPane().add(comboBox);
}
private void initialize() {
/*...*/
// ComboBox
JComboBox<String> comboBox = new JComboBox<String>();
setComboboxInstituicao(comboBox);
JLabel lblSelecioneUmaInstituio = new JLabel("Select an institution:");
lblSelecioneUmaInstituio.setBounds(22, 93, 206, 15);
frame.getContentPane().add(lblSelecioneUmaInstituio);
// Calls another window for data insert
JButton btnNovaInstituio = new JButton("New Institution");
btnNovaInstituio.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
adicionaInstituicao window = new adicionaInstituicao();
window.frame.setVisible(true);
}
});
/*...*/
}
}
I used a setCombobox function to run each time the framework reloads, but it still not working.

Add Enter key as JButton accelerator

I'm building simple chat application with simple GUI, but a I have a problem assigning Enter key to Send button. Right now it is quite unpractical pressing Alt+Enter.
public void buildInterface() {
//some other components
btnSend = new JButton("Send");
btnExit = new JButton("Exit");
btnSearch=new JButton("Search");
btnSend.setMnemonic(KeyEvent.VK_ENTER);
JPanel box=new JPanel();
add(box, BorderLayout.SOUTH);
box.add(tfInput);
box.add(btnSend);
box.add(btnExit);
box.add(btnSearch);
}
When the button is focused, under most look and feels the Enter will activate the button.
You can, however, assign a button to be the "default" button for the window, which will be activated when the Enter key pressed, so long as the focused component does not consume it.
See How to Use Root Panes and JRootPane#setDefaultButton for more details
Add following code to your Util class
public static void bindKeyStroke(final JButton btn, String ks) {
final ActionListener[] alist = btn.getActionListeners();
if (alist.length != 0) {
AbstractAction action = new AbstractAction(btn.getText(), btn.getIcon()) {
#Override
public void actionPerformed(ActionEvent e) {
for (ActionListener al : alist) {
ActionEvent ae = new ActionEvent(e.getSource(), e.getID(), Action.ACCELERATOR_KEY);
al.actionPerformed(ae);
}
}
};
KeyStroke keyStroke = KeyStroke.getKeyStroke(ks);
btn.setAction(action);
btn.getActionMap().put(Action.ACCELERATOR_KEY, action);
btn.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, Action.ACCELERATOR_KEY);
}
}
Goto frame, dialog or panel constructor and add after initComponent();
Util.bindKeyStroke(<your button>, "alt enter");
Fix double action, in action performed
if (evt.getActionCommand().equals(Action.ACCELERATOR_KEY)) {
// Your send action here
}

Java moving back and forth between content in runnable Jar file

I'm quite new to programming so I don't know the right way to do things and have been just experimenting a bit. I want to create a runnable where I can move back and forth between different content. The following works when run from inside eclipse, but if I export it as a JAR file, once I've moved forward once and then back again, moving forward won't give me the content anymore, but just the back button.
I tried something like this:
public class TestMain extends JFrame {
static PanelClass panel;
static boolean inUse = false;
public static void main(String[] args) {
panel = new PanelClass();
final TestMain test = new TestMain();
final Container container = test.getContentPane();
container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS));
test.setSize(500, 500);
final JButton back = new JButton("Back");
back.setAlignmentX(Component.CENTER_ALIGNMENT);
back.setMaximumSize(new Dimension(200, 80));
back.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
test.getContentPane().removeAll();
test.setContentPane(container);
test.getContentPane().revalidate();
}
});
final JButton exit = new JButton("Exit");
exit.setAlignmentX(Component.CENTER_ALIGNMENT);
exit.setMaximumSize(new Dimension(200, 80));
exit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
JButton problem = new JButton("Problem");
problem.setMaximumSize(new Dimension(200, 80));
problem.setAlignmentX(Component.CENTER_ALIGNMENT);
problem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
inUse = true;
test.setContentPane(panel);
test.getContentPane().add(back);
test.getContentPane().revalidate();
}
});
container.add(problem);
container.add(exit);
test.setVisible(true);
test.setDefaultCloseOperation(EXIT_ON_CLOSE);
test.setLocationRelativeTo(null);
while (true) {
while (!panel.stop && !inUse) {
}
inUse = false;
panel = new PanelClass();
test.setContentPane(panel);
test.getContentPane().add(back);
test.getContentPane().revalidate();
}
}
}
And the class for what I want to have as the second content:
public class PanelClass extends JPanel {
JTextArea text = new JTextArea("Some text here!" + '\n' + '\n');
JButton button1 = new JButton("Button 1");
JButton button2 = new JButton("Button 2");
boolean stop = false;
public PanelClass() {
text.setEditable(false);
text.setMaximumSize(new Dimension(300, 300));
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
Dimension d = new Dimension(200, 60);
button1.setAlignmentX(Component.CENTER_ALIGNMENT);
button1.setMaximumSize(d);
button2.setAlignmentX(Component.CENTER_ALIGNMENT);
button2.setMaximumSize(d);
this.add(text);
this.add(button1);
this.add(button2);
}
}
What is the actual working way to do this? What if I have a lot of windows I'd like to be able to move back and forth between? I know it's a lot of bad/possibly-hard-to-read code, but I hope someone could help me out.
This is the code that runs when you press "Problem":
test.setContentPane(panel);
test.getContentPane().add(back);
test.getContentPane().revalidate();
and this is the code that runs when you press "Back":
test.getContentPane().removeAll();
test.setContentPane(container);
test.getContentPane().revalidate();
What is the sequence of calls when you press "Problem" then "Back" then "Problem"? It's this. (The revalidate() calls won't mess anything up, so I won't show them)
// Problem
test.setContentPane(panel);
test.getContentPane().add(back);
// Back
test.getContentPane().removeAll();
test.setContentPane(container);
// Problem
test.setContentPane(panel);
test.getContentPane().add(back);
Notice that you set the panel as the content pane, and then remove all the components from it when "Back" is pressed. The next time you press "Problem", the panel has no components on it, because you removed them.
did you try exporting as a runnable jar and choose package required libraries into generated jar when you exported as JAR from eclipse?

How to do an action when a certain button is clicked

Basically, at the moment I am doing certain actions that are being held in an ArrayList and when I click the Play Button, they are being output to a TextArea. I have two other buttons, Start and Stop.
When I click Start, every action that I do is supposed to start recording.
When i click Stop, it stops recording the actions.
When I click Play, the actions are supposed to be printed in the text area.
I have got the hard bit working but I just can't seem to implement the start and stop buttons. I will attach part of my code so you are able to see. Thanks in advance!!
public class jPanelBottom extends javax.swing.JPanel
{
private JTextField jtfBoundaryLength, jtfArea;
private JSlider jsShapes;
private JLabel jLabelBoundaryLength, jLabelArea, jLabelSlider;
private JButton jbStart, jbStop, jbPlay;
public static ActionPanel yes;
public jPanelBottom()
{
initComponents();
jbStart = new JButton();
jbStop.setText("Start");
jbStart.setSize(80, 25);
jbStart.setLocation(400, 95);
this.add(jbStart);
jbStop = new JButton();
jbStop.setText("Stop");
jbStop.setSize(80, 25);
jbStop.setLocation(500, 95);
this.add(jbStop);
jbPlay = new JButton();
jbPlay.setText("Play");
jbPlay.setSize(80, 25);
jbPlay.setLocation(600, 95);
this.add(jbPlay);
jbPlay.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
try{
//jbStart.addActionListener(this);
{
jbPlay.addActionListener(this);
ArrayList<String> list = MyFrame.shape1.getArrayList();
for (String s : list)
{
ActionPanel.jtaWoof.append(s);
ActionPanel.jtaWoof.append("\n");
}
}}catch(Throwable ex){}}
});
}
I really appreciate any help!!
The best way is to add a general actionPerformed:
public class Frame extends JFrame implements ActionListener{
[...]
public Frame(){
JButton Test = new JButton("Nutton Name");
[...]
Test.addActionListener(this);
}
#Override
public void actionPerformed(ActionEvent e){
Object src = e.getSource();
if(src == Test){
System.out.print("You've pressed Test!");
}
}
}
Don't forget to add the .addActionListener and to implement ActionListener to the class.
This is much easier than adding one every single time.

Timer cannot stop (maybe the GUI error)

I'm trying to create animation for a traffic light simulation that uses a timer. There is a button to stop the simulation, but clicking it does not seem to affect the animation. I did check in the animation but the animation seem like different places. Please help.
In the main class:
DataModels dm = new DataModels();
Simulation sm = new Simulation(dm);
sm.go();
Here is the simulation class:
public class Simulation extends JPanel implements ActionListener {
DataModels dm;
Timer tm = new Timer(20, this);
private boolean ss = false;
public Simulation(DataModels dm) {
this.dm = dm;
// redLightTime= dm.getRedLight()*1000;
}
public void go() {
sm = new Simulation(dm);
simulation = new JFrame();
simulation.setTitle("Traffic light and Car park Siumulation");
simulation.setSize(800, 700);
simulation.setResizable(false);
simulation.setVisible(true);
simulation.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
simulation.add(sm, BorderLayout.CENTER);
// Command button panel
JPanel command = new JPanel();
command.setPreferredSize(new Dimension(800, 100));
// Pause or play button
JButton pauseplayB = new JButton("Pause");
pauseplayB.setSize(new Dimension(50, 50));
pauseplayB.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Execute when button is pressed
ss = true;
System.out.println("You clicked the button");
}
});
command.add(pauseplayB);
JButton stopB = new JButton("Stop");
JButton saveB = new JButton("Save");
command.setLayout(new GridLayout(1, 1));
command.add(stopB);
command.add(saveB);
simulation.add(command, BorderLayout.SOUTH);
}
Now paintComponent will change based on timer change. The following code is also in the Simulation class.
public void paintComponent(Graphics g) {
// Many other actions
// ....
startAnimation();
}
public void startAnimation() {
if ( !false) {
tm.start();
} else {
tm.stop();
}
// Checking button click
System.out.println(ss);
}
According to the console output, the ss value never changes.
The button's action listener should call the function to stop the timer somehow and not rely on the paint event to do it.
EDIT: Here is some code :)
public void actionPerformed(ActionEvent e) {
// Execute when button is pressed
ss = true;
System.out.println("You clicked the button");
startAnimation();
}
And the startAnimation method should have if(!ss) instead of if(!false)
In addition to JTMon's suggestion, your startAnimation method contains a logic bomb
public void startAnimation() {
if ( !false) { //<-- this will ALWAYS be true
tm.start();
} else {
tm.stop();
}
// Checking button click
System.out.println(ss);
}
The if statement that controls the timer will ALWAYS try & start the timer

Categories