java - 为什么线程运行时 JButton 不起作用?

标签 java swing

我的应用程序中有 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/

相关文章:

java - 我如何使用 Java 与 MySQL 交互?

java - 斯波克和梅文。使用@Unroll 的测试因错误而失败,但 Maven 输出中的占位符未填充迭代数据

java - Swing 完成绘制时通知

java - 使用 TextAction 实现带有 actionPerformed 的 JMenu

java - 如何保存使用 OAuth 2 (Spring) 登录的用户?

java - 如何让 onFocus() 用 Selenium 触发

java - 在 Java 中使用长列表作为映射键

java - JPanel 填充整个 JFrame

java - 如何显示列名并为jtable设置滚动条?

java - 如何更改另一个线程中 JLabel 的图像