Java 如何在jframe中启动和停止循环

Java 如何在jframe中启动和停止循环,java,swing,loops,jframe,Java,Swing,Loops,Jframe,我是java新手 我需要将数据字符串输出到输出端口,直到在数据端口上收到字符串,然后执行其他操作。 暂时撇开com端口的问题不谈,我试图简单地使用按钮启动然后停止数据来模拟流,结果失败得很惨。 这是我创建的代码。我想开始输出到文本区域,直到我按下停止按钮 import java.awt.BorderLayout; import java.awt.EventQueue; import javax.swing.JFrame; import javax.swing.JPanel; import ja

我是java新手 我需要将数据字符串输出到输出端口,直到在数据端口上收到字符串,然后执行其他操作。 暂时撇开com端口的问题不谈,我试图简单地使用按钮启动然后停止数据来模拟流,结果失败得很惨。 这是我创建的代码。我想开始输出到文本区域,直到我按下停止按钮

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JTextArea;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.concurrent.TimeUnit;


public class WriteToWindow extends JFrame {

    private JPanel contentPane;
    private final static String newline = "\n";

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    WriteToWindow frame = new WriteToWindow();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public WriteToWindow() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        // try adding final
        final JTextArea textArea = new JTextArea();
        textArea.setRows(10);
        textArea.setBounds(27, 23, 377, 142);
        contentPane.add(textArea);

        JButton btnStart = new JButton("Start");
        btnStart.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
            // start writing to the text area
                int i = 1;
                textArea.append("You clicked start" + newline);
                do {
                    textArea.append("Iteration " + Integer.toString(i) + newline);  
                    i++;
                    // wait a second
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } while (true);// forever
            }
        });
        btnStart.setBounds(25, 188, 89, 23);
        contentPane.add(btnStart);

        JButton btnStop = new JButton("Stop");
        btnStop.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //stop writing data to the text area
                textArea.append("You clicked stop" + newline);
                }
        });
        btnStop.setBounds(151, 188, 89, 23);
        contentPane.add(btnStop);
    }
}

这种方法不起作用,因为它会阻塞事件分派线程,阻止它处理可能引发的任何新事件,包括
repaint
事件。这将基本上挂起您的程序

相反,您需要将循环的执行卸载到某种后台
线程

虽然您当然可以使用
线程
,但您将负责确保不违反Swing的单线程特性,即确保在事件调度线程的上下文中执行对UI的任何更新

为此,我建议使用
SwingWorker
,因为它允许您在后台(单独的
线程
)工作,同时提供易于使用的功能将更新同步回EDT

看看,尤其是