我的应用程序中有 2 个按钮。当按下“开始”按钮时,我创建了一个线程来更新 JTextArea。当按下“停止”按钮时,我想停止线程。但是,当按下“开始”时,“停止”在线程完成之前不起作用。有人可以帮助我吗?
public class JTextAreaDemo implements ActionListener {
JFrame frame;
JPanel jp;
JTextArea jta;
JButton jb1, jb2;
volatile boolean stop = true;
void init() {
frame=new JFrame("Test");
jp=new JPanel();
jta=new JTextArea(7,30);
jb1 = new JButton("Start");
jb1.addActionListener(this);
jb2 = new JButton("Stop");
jb2.addActionListener(this);
jta.setEditable(false);
jta.setLineWrap(true);
jta.setWrapStyleWord(true);
JScrollPane jsp=new JScrollPane(jta);
Dimension size=jta.getPreferredSize();
jsp.setBounds(110,90,size.width,size.height);
jp.add(jsp);
jp.add(jb1);
jp.add(jb2);
frame.add(jp);
frame.setSize(400,200);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] agrs){
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new JTextAreaDemo().init();
}
});
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == jb1) {
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0; i<100000 && stop; ++i) {
final String str = "hello:"+i+"\n";
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
jta.append(str);
jta.setCaretPosition(jta.getDocument().getLength());
});
}
}
}).start();
System.out.println("begin");
} else if (e.getSource() == jb2) {
System.out.println("stop");
stop = false;
}
}
}
最佳答案
因为SwingUtilities.invokeLater
将一个操作放入队列中以便稍后执行。你的循环for(int i=0; i<100000 && stop; ++i)
将很快将十万个操作放入队列并完成。这将在您按停止键之前完成。
之后,所有操作都会被执行。
解决此问题的一种方法是使用 SwingUtilities.invokeAndWait
。这也会将一个操作放入队列中,但随后它将等待 Swing 线程执行该操作,然后再继续。这意味着循环本身将花费与其计划的所有操作一样长的时间来完成,并且它将看到 stop
的更改。标志。
(注意:您可以考虑将 stop
重命名为 keepRunning
- 因为目前,您希望在将 stop
设置为 false
时停止。)
关于java - 为什么线程运行时 JButton 不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57754633/