JFrame在连续运行代码时冻结

时间:2013-03-21 05:42:10

标签: java multithreading swing event-dispatch-thread

我在使用JFrame时遇到问题,而btnRun会冻结 持续运行代码。以下是我的代码:

  1. 点击MainLoop()后,我调用了函数ActionListener btnRun_Click = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { MainLoop(); } };

    MainLoop()
  2. 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()
  3. btnHalt函数中,while循环继续运行,直到Running为true问题是如果我想停止循环我必须将Running设置为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; } };

    btnHalt
  4. textarea没有响应,整帧被冻结,也没有 显示{{1}}中的任何日志。

1 个答案:

答案 0 :(得分:2)

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

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

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

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

您可以通过多种方式解决此问题。您可以使用SwingUtilities.invokeLaterSwingWorker

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

阅读Concurrency in Swing

<强>更新

只是让你理解;)

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

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