Java JFrame在连续运行代码时冻结

Java JFrame在连续运行代码时冻结,java,multithreading,swing,event-dispatch-thread,Java,Multithreading,Swing,Event Dispatch Thread,我在使用JFrame时遇到问题,它在 持续运行代码。下面是我的代码: 单击btnRun,我调用了函数MainLoop(): 实现MainLoop(): 在MainLoop()函数中,while循环持续运行,直到运行为真。问题是,如果我想停止while循环,我必须将running设置为false,这在另一个按钮btnHalt上完成: ActionListener btnHalt_Click = new ActionListener() { @Override public v

我在使用
JFrame
时遇到问题,它在 持续运行代码。下面是我的代码:

  • 单击
    btnRun
    ,我调用了函数
    MainLoop()

  • 实现
    MainLoop()

  • MainLoop()
    函数中,while循环持续运行,直到运行为真。问题是,如果我想停止while循环,我必须将running设置为false,这在另一个按钮
    btnHalt
    上完成:

    ActionListener btnHalt_Click = new ActionListener() {
    
        @Override
        public void actionPerformed(ActionEvent e) {
            textBox1.append("Poll loop stopped\r\n");
            System.out.println("Hoper Stopped");
            Running = false;
        }
    };
    
  • 但是
    btnhat
    没有响应,整个帧被冻结,也没有响应
    textarea

    Swing中显示任何日志是一个单线程框架。也就是说,有一个线程负责将所有事件分派到所有组件,包括重绘请求

    任何停止/阻止此线程的操作都将导致UI“挂起”

    Swing的第一条规则是,永远不要在事件调度线程上运行任何阻塞或耗时的任务,而应该使用后台线程

    这让你进入了挥杆的第二条规则。切勿在EDT之外创建、修改或与任何UI组件交互

    有很多方法可以解决这个问题。您可以使用
    SwingUtilities.invokeLater
    SwingWorker

    SwingWorker
    通常更简单,因为它提供了许多简单易用的方法,可以自动将这些调用重新同步到EDT

    通读

    已更新

    让你明白;)

    您的
    MainLoop
    方法不应该在EDT的上下文中执行,这非常糟糕


    另外,除了EDT之外,您不应该与任何线程中的任何UI组件进行交互。

    我已经为MainLoop创建了单独的线程,但是Jframe可以工作,但是当单击BTN时,它不会停止,因为线程正在连续运行。您可以给我任何示例代码吗请学习java命名约定并坚持它们。
    void MainLoop()
    {
        Hopper = new CHopper(this);
        System.out.println(Hopper);
        btnRun.setEnabled(false);
        textBox1.setText("");
        Hopper.getM_cmd().ComPort = helpers.Global.ComPort;
        Hopper.getM_cmd().SSPAddress = helpers.Global.SSPAddress;
        Hopper.getM_cmd().Timeout = 2000;
        Hopper.getM_cmd().RetryLevel = 3;
    
    
        System.out.println("In MainLoop: " + Hopper);
    
        // First connect to the validator
        if (ConnectToValidator(10, 3))
        {
            btnHalt.setEnabled(true);
            Running = true;
    
            textBox1.append("\r\nPoll Loop\r\n"
                    + "*********************************\r\n");
        }
    
        // This loop won't run until the validator is connected
        while (Running)
        {
            // poll the validator
            if (!Hopper.DoPoll(textBox1))
            {
                // If the poll fails, try to reconnect
                textBox1.append("Attempting to reconnect...\r\n");
                if (!ConnectToValidator(10, 3))
                {
                    // If it fails after 5 attempts, exit the loop
                    Running = false;
                }
            }
            // tick the timer
                    // timer1.start();
            // update form
            UpdateUI();
            // setup dynamic elements of win form once
            if (!bFormSetup)
            {
                SetupFormLayout();
                bFormSetup = true;
            }
    
        }
    
        //close com port
        Hopper.getM_eSSP().CloseComPort();
    
        btnRun.setEnabled(true);
        btnHalt.setEnabled(false);
    }
    
    ActionListener btnHalt_Click = new ActionListener() {
    
        @Override
        public void actionPerformed(ActionEvent e) {
            textBox1.append("Poll loop stopped\r\n");
            System.out.println("Hoper Stopped");
            Running = false;
        }
    };