问题
After starting infinite loop, I am unable to close JFrame.
I want to stop infinite loop using stop button.
I am starting an infinite loop using start button. I want close that loop using stop button.
if(stop.getModel().isPressed()){break;} is not working
actionListener used to identify button click and using break statement to terminate while loop is also not working
import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*; public class NewClass1 { private String arg = ""; public NewClass1() { JFrame frame = new JFrame("Datacolor software automate"); JButton stop = new JButton("STOP"); stop.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { arg = (String)ae.getActionCommand(); System.out.println(arg); } }); JButton button = new JButton("Start"); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { int i = 0; while (true) { try { System.out.println(i); i++; if(arg.equals("STOP")) { break; } } catch (Exception e) { System.out.println(e.toString()); } } } }); frame.add(button); frame.add(stop); frame.setLayout(new FlowLayout()); frame.setSize(300,300); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new NewClass1(); } }); } }
On clicking stop button infinite loop must terminate. I able not able to use any buttons in JFrame after starting infinite loop using start buttton.
回答1:
You cannot click "Stop" button in the first place, and this is because you run a big task (the while(true)
part of your code) in the Event Dispatch Thread which will cause your whole GUI to freeze.
In order to avoid this, and make it work, you will have to use a SwingWorker. A class that allows you to run long/heavy tasks in the background and (optionally) publish them in GUI.
Then, if you want to cancel this SwingWorker, a call to its cancel()
method will be enough.
Take a look at the following example:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class NewClass1 {
private String arg = "";
private SwingWorker<Void, Integer> worker;
public NewClass1() {
JFrame frame = new JFrame("Datacolor software automate");
JButton stop = new JButton("STOP");
stop.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
worker.cancel(true);
}
});
JButton button = new JButton("Start");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
initializeWorker();
worker.execute();
}
});
frame.add(button);
frame.add(stop);
frame.setLayout(new FlowLayout());
frame.setSize(300, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void initializeWorker() {
worker = new SwingWorker<Void, Integer>() {
@Override
protected Void doInBackground() throws Exception {
int i = 0;
while (!isCancelled()) {
i++;
publish(i); // give this i to "process" method
}
return null;
}
@Override
protected void process(List<Integer> chunks) {
int i = chunks.get(0);
System.out.println(i);
}
};
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new NewClass1());
}
}
来源:https://stackoverflow.com/questions/54762919/stop-infinite-loop-using-stop-button