2

I'm currently programming in Java. When the user presses the program's start button, I'd like a loop to start. But then I'd like the user to have the ability to stop the loop with a stop button:

public class Program {
    private boolean active;

    // MVC stuff...

    private class StartListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            // Do stuff...

            active = true;
            hotelCalifornia();
        }
    }

    private class StopListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            // Do stuff...

            active = false;
        }
    }

    public void hotelCalifornia() {
        while (this.active) {
            // The program never leaves!
        }
    }
}

But once the loop is started, the program only performs the actions of the loop. Is there a way around this? Is there a better way to accomplish my goal?

Thanks!

Peter
  • 4,021
  • 5
  • 37
  • 58

5 Answers5

4

First, you'd have to start the loop in a new Thread.

And then, when the user presses stop(), call thread.interrupt()

Inside the loop add:

if (Thread.currentThread().isInterrupted()) {
    break;
}
Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
4

All the events in a Java Swing application is called in a single Event Thread.

You should create a Swing Timer to call whatever method you want whenever so frequent.

Nican
  • 7,825
  • 3
  • 27
  • 26
1

I suggest putting the logic in the while loop in a runnable

class basicThread implements Runnable {
    public void run() {
        while (true) {
            // Put the stuff in your while loop here
        }
    }
}

Set up a thread to execute your runnable

// Create a thread to execute your runnable
Thread thread = new Thread(new basicThread());

Then call below in StartListener

thread.start();

And below in StopListener

thread.interrupt()
ClassicThunder
  • 1,896
  • 16
  • 25
1

There are two things to consider.

First, you are creating a long running process within the Event Dispatch Thread. This is something that you should never do. As Nican points out, all the GUI events in your Swing app will be called in this thread. When the user presses the Start button, your actionPerformed in your StartListener will be called in the EDT. Read here for more info on Swing Threading.

This leads to the second point: you will want to run your hotelCalifornia in a different Thread. You can keep a ref to this thread around such that you can call thread.interrupt() as Bozho points out. You also have the option of working with your own implementation, but you will want to make sure that your active var is declared as volatile so that the state of the boolean is immediately accessible to your new thread once it is updated.

Community
  • 1
  • 1
akf
  • 38,619
  • 8
  • 86
  • 96
1

An option would be to use a SwingWorker. When you no longer want it to run, call the cancel() method on it, and check for isCancelled() in your loop.

AndrewBourgeois
  • 2,634
  • 7
  • 41
  • 58