JFrame在连续运行代码时冻结 [英] JFrame freezes while running the code continuously

查看:133
本文介绍了JFrame在连续运行代码时冻结的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 JFrame 时遇到问题,这会在
连续运行代码时冻结。下面是我的代码:

I have problem while working with JFrame, which get freezes while running the code continuously. Below is my code:


  1. 点击 btnRun ,我打电话给函数 MainLoop()

ActionListener btnRun_Click = new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent e) {
        MainLoop();
    }
};


  • 实施 MainLoop()

    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);
    }
    


  • MainLoop()函数,while循环继续运行,直到Running为true问题是如果我想停止while循环我必须将Running设置为false,这是在另一个按钮 btnHalt

  • In the MainLoop() function, the while loop is running continuesly until the Running is true problem is that if i want to stop that while loop i have to set Running to false which is done at another button 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;
        }
    };
    


  • 但是 btnHalt 没有响应,整帧被冻结,也没有
    显示 textarea 中的任何日志。

    but btnHalt is not responding, whole frame is get freeze, also not showing any log in the textarea.

    推荐答案

    Swing是一个单线程框架。也就是说,有一个线程负责将所有事件分派给所有组件,包括重绘请求。

    Swing is a single thread framework. That is, there is a single thread responsible for dispatching all the events to all the components, including repaint requests.

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

    Any action which stops/blocks this thread will cause your UI to "hang".

    Swing的第一条规则,从不在事件调度线程上运行任何阻塞或耗时的任务,相反,你应该使用后台线程。

    The first rule of Swing, NEVER run any blocking or time consuming tasks on the Event Dispatching Thread, instead, you should use a background thread.

    这会让你进入Swing的第二条规则。永远不要创建,修改或与EDT之外的任何UI组件交互。

    This runs you smack into the second rule of Swing. Never create, modify or interact with any UI component outside of the EDT.

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

    There are a number of ways you can fix this. You could use SwingUtilities.invokeLater or a SwingWorker.

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

    SwingWorker is generally easier, as it provides a number of simple to use methods that automatically re-sync there calls to the EDT.

    阅读 Swing中的并发

    已更新

    只是让您理解;)

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

    Your MainLoop method should not be executed within the context of the EDT, this is very bad.

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

    Also, you should not be interacting with any UI component from any thread other the then the EDT.

    这篇关于JFrame在连续运行代码时冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆