Java Swing 线程:执行逻辑命令时 GUI 挂起

Posted

技术标签:

【中文标题】Java Swing 线程:执行逻辑命令时 GUI 挂起【英文标题】:Java Swing Threading: GUI hangs when logic commands are executed 【发布时间】:2018-04-18 08:10:54 【问题描述】:

我目前正在从事一个涉及 Parrot A.R. 控制开发的项目。无人机 2.0 强力版。

为此,我们使用 YaDrone 库 (https://vsis-www.informatik.uni-hamburg.de/oldServer/teaching/projects/yadrone/) 来控制无人机。围绕这个库创建了一个 DroneController 类以进行更多控制。这实质上是托管无人机使用的所有逻辑。

在 Java Swing 中开发了一个 GUI 来显示有关无人机的各种信息。

我们遇到的问题是,当程序执行时,也就是无人机启动时,GUI 会打开,但会挂起/冻结,直到无人机发送并执行了无人机的所有命令。

显然,我们希望 GUI 在命令发送到无人机的同时更新。

我们一直在试验 SwingUtilities 之类的东西,但没有成功。这是当前的主类:

Main Class 该项目的整个代码可以在这里看到:https://github.com/tMascagni/CDIO_3/tree/dev(特别是在 dev 分支中。)

其中最重要的部分是ui包,Main.java和DroneController.java。

如果有人对如何解决这个问题有任何想法,我非常感谢任何反馈!

【问题讨论】:

你忘记了 Swing 的第一条规则。不要在 EDT(事件调度线程)上执行代码。 阅读concurrency in Swing。在您的情况下,您需要 SwingWorker 来提供所需的功能。 @Kayaman 我认为第一条规则是“在 EDT 线程上 /only/ 执行 Swing 代码”。那将是另一条规则,可能是第二条:“在其他非 EDT 线程上执行可能需要时间的非摆动代码” @tucuxi 这是另一条第一条规则! 【参考方案1】:

一般来说,以下方法可行:

   Thread t = new Thread(()->
      // this code will be executed outside the EDT thread, 
      // and will not make the interface non-responsive
      // ...

      SwingUtilities.invokeLater(()->
         // and this code will execute once the above code is finished,
         // within the EDT thread, and can report on results
      );
   ).start();

使用SwingWorker 是一种更精简但实施起来更复杂的方法。

【讨论】:

以上是关于Java Swing 线程:执行逻辑命令时 GUI 挂起的主要内容,如果未能解决你的问题,请参考以下文章

Swing理解Swing中的事件与线程

Swing:关于Java界面编程的第一课,如何正确的处理界面中的线程

由java中的另一个线程刷新GUI(swing)

Java:Swing 库和线程安全

强制 Java 刷新 Java Swing GUI

我在对齐元素时遇到问题(Java GUI / Swing);