1

I am trying to have my program break out of a while loop when a button on the gui is pressed.

I have a thread which launches the GUI thread and the waits until an apply button is pressed. Here is the code:

public void run() {     

        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }           
        });

        // Wait until apply button clicked and set team
        while(true) {

            applyClicked = gui.getApplyClicked();
            if (applyClicked == true) {
                teamYellow = gui.getTeam();
                break;
            }   
        }

However even when I click apply and the applyClicked becomes true within the GUI it does not execute that if statement.

However if I add a print line underneath the while true it works ok.

I also debugged it running line by line and the variables set correctly and it works.

Why doesn't this work when I don't have a println? Is it something to do with threads?

Thanks

sam
  • 2,469
  • 8
  • 37
  • 57

2 Answers2

5

You're executing a busy-wait loop, which will I guess take all of your cpu power. You should instead add an actionListener on your apply-button and do your stuff in the actionPerformed method.

Fredrik LS
  • 1,480
  • 9
  • 15
  • Hi thats what I am currently doing in the gui class. The actionPerformed method changes the boolean which says whether the button has been clicked or not. I then use a getter in the same class to get this boolean in my class which contains the loop above. – sam Feb 24 '12 at 20:44
  • Couldn't you add this class as a listener on the buttons event? Then you could remove the busy-wait loop which you sure don't want to have. – Fredrik LS Feb 24 '12 at 20:49
  • Sorry not too sure how to do that. So the class that currently has the busy-wait loop is called Runner, and the gui class is called MainGui with its instance called gui in the Runner class. Currently I call `log.apply.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) {...` in the MainGui class where log is a panel containing the button. How would I add the Runner class as a listener – sam Feb 24 '12 at 21:04
  • 1
    `public class Runner implements ActionListener { public void actionPerformed(ActionEvent e) { do stuff in here }` and then you could for instance add the `Runner` as an argument to the MainGui constructor and in the constructor do `public MainGui(Runner runner) { log.apply.addActionListener(runner); }` – Fredrik LS Feb 24 '12 at 21:14
  • Ok, so the code that I had in the action listener for the apply button in MainGui now goes in the action listener within Runner? I have added the code you suggested to MainGui and then moved the action code to Runner however it does nothing when the button is clicked. – sam Feb 24 '12 at 21:41
  • 1
    Could you update your code example in the question? Then I might see what's wrong. – Fredrik LS Feb 24 '12 at 21:50
  • Never mind I got it too work. I was instantiating the Gui before I called the invokeLater method. Thanks very much for your help – sam Feb 24 '12 at 21:51
  • You're welcome, I'm glad if you mark the question as answered:-). – Fredrik LS Feb 24 '12 at 21:54
0

This may not be the answer you are looking for exactly, but just in case, define applyClicked outside the loop and declare the loop as while(!applyClicked) so that the break is not needed, because if applyClicked is true, the loop will exit on its own. If that still doesn't work, run the new code with the debugger. This may or may not work, it's just a suggestion.

rcplusplus
  • 2,767
  • 5
  • 29
  • 43