Stop and start the loop using the button

I am trying to control the while loop in my program to stop and start based on user input. I tried to do this with a button, and the β€œstart” part of it works, but then the code goes into an endless loop, which I cannot stop without manually completing. Following is all my code: Header Class

package test; import javax.swing.JFrame; public class headerClass { public static void main (String[] args){ frameClass frame = new frameClass(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(150,75); frame.setVisible(true); } } 

Frame class

 package test; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class frameClass extends JFrame { private JButton click; public frameClass(){ setLayout(new FlowLayout()); click = new JButton("Stop Loop"); add(click); thehandler handler = new thehandler(); click.addActionListener(handler); } private class thehandler implements ActionListener{ public void actionPerformed(ActionEvent e){ if(e.getSource()==click){ looper loop = new looper(); looper.buttonSet = !looper.buttonSet; } } } } 

Loop class

 package test; public class looper { public static boolean buttonSet; public looper(){ while (buttonSet==false){ System.out.println("aaa"); } } } 

How can I fix this and stop if, having entered an infinite loop, please?

+6
source share
2 answers

Swing is a single-threaded infrastructure, which means that while the cycle is running, the Dispatcher event flow is blocked and cannot process new events, including redraw requests ...

You need to run your Looper class inside your own thread context. It would also mean that your loop flag should be declared volatile or you should use AtomicBoolean so that it can be checked and changed at the flow boundaries

For instance...

 public class Looper implements Runnable { private AtomicBoolean keepRunning; public Looper() { keepRunning = new AtomicBoolean(true); } public void stop() { keepRunning.set(false); } @Override public void run() { while (keepRunning.get()) { System.out.println("aaa"); } } } 

Then you could use something like ...

 private class thehandler implements ActionListener { private Looper looper; public void actionPerformed(ActionEvent e) { if (e.getSource() == click) { if (looper == null) { looper = new Looper(); Thread t = new Thread(looper); t.start(); } else { looper.stop(); looper = null; } } } } 

to run it ...

See Concurrency in Swing and Concurrency in Java for more details.

Also be careful, Swing is not thread safe, you should never create or modify the user interface from the EDT context

+8
source

The problem is that you are starting an endless loop and trying to end it in the same thread. This does not work because the VM performs one task in a thread after another. He would execute a command to stop the looper immediately after the loop ended, but the infinite loop never ends. So it is impossible to stop. You need to create a second Thread for the looper. That way you can stop it from the main thread.

+2
source

Source: https://habr.com/ru/post/980188/


All Articles