在EDT线程中创建JFrame实例是不好的做法吗?

时间:2020-06-04 18:46:34

标签: java swing

我正在阅读有关使用javax.swing的Java 2D游戏的教程,并且在该教程中,他们使用了:

EventQueue.invokeLater(() -> {
      JFrame ex = new UtilityTimerEx();
      ex.setVisible(true);
});

但是本教程没有解释EventQueue.invokeLater(...)的作用,所以我对此进行了研究,据我了解,该方法用于在 EDT 中运行代码。应该只用于GUI更改,因此JFrame实例的初始化是否不应该写在EventQueue.invokeLater(...)之外?这样会更好吗?

JFrame ex = new UtilityTimerEx();
EventQueue.invokeLater(() -> {
      ex.setVisible(true);
});

1 个答案:

答案 0 :(得分:3)

否; EDT应该用于您可以召集的所有GUI工作。与用户界面完全无关的任何计算(不进行,更改或读取用户界面的 ANY 部分),那些都应放在EDT。

在EDT中绝对不能做两件事:

  1. 常见问题:切勿“阻塞”-任何可能导致CPU冻结的代码,任何网络连接或任何类型的文件读取,或等待另一个线程(可能通过将其压入) (例如阻塞队列)或Thread.sleep-全部为僵尸。如果这样做,您的应用程序将显得无响应,并且操作系统很快就会询问最终用户是否要关闭崩溃的应用程序。请注意,各种库显然都在内部执行此操作,这同样很糟糕。不要从EDT内部查询数据库;该查询通过网络发出,需要等待答案:EDT中的两个大问题。将其移植到另一个线程,完成数据库查询后,使用EventQueue.invokeLater以更改UI小部件的形式将信息中继回去,因为从EDT外部修改UI也是一个大难题。

  2. 不常见:需要很长时间的工作。从字面上看,使CPU保持忙碌而不会暂停。我不知道,您需要挖掘比特币或对视频进行编码或诸如此类。是的,一旦它成长为一项众所周知需要花费很长时间的工作,是的,请将其放入线程中。

NB:更现代的SwingWorker类可能非常有用,使用它比滚动自己的线程要容易得多,并且不要忘记将所有可修改UI的代码包含在invokeLater中。

相关问题