簡體   English   中英

為什么在線程運行時JButton無法正常工作?

[英]Why JButton is not working when a thread is running?

我的應用程序中有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時,您想停止。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM