我可以运行两个EDT吗?

Pur*_*ret 1 java user-interface event-dispatch-thread

这主要是一个理论问题。下面的示例使我想到了它,但这可能不是最好的示例。请假设以下原因是具体的,暂时无法解决。

我正在运行的程序具有一个可选的调试框架,该框架在程序启动时创建,并且可以通过用户按按钮/键盘快捷方式使其可见。

我的问题是,由于我在EDT上的进程很长,如果它由于某种原因挂起或失败,我想立即查看,而不是等待该线程结束运行,以更新调试日志框架。

我的解决方案是让两个单独的GUI具有两个单独的EDT,并由一个单独的线程更新它们。

这可能吗,还是我做不到?我尚未找到任何可以向我展示如何使用的在线资源。我知道EDT应该是单线程的,但是如果我使线程不纠缠,我可以有两个吗?请?

Mar*_*rco 5

答案很简单:不,您不能拥有2个EDT,这是不可能的。但是,您不会被冻结的GUI所困扰,可以使用一些选项。

首先,两个重要规则:

  1. 切勿在EDT中进行冗长的计算。曾经
  2. 切勿从EDT外部操纵Swing组件。曾经

违反第一条规则将导致您的GUI被冻结,并且在此期间未处理任何类型的事件。这包括在计算过程中要执行的GUI更新,直到更新完成后才会显示。

后者常常被忽略,这在大多数情况下会不为人所知,但是它可以而且会咬你的屁股,然后在大多数情况下回头去修理它是一个巨大的皮塔饼。因此,从一开始就以正确的方式进行操作。会发生什么?组件可能突然显示为断线状态,它们可能显示为白色,或者整个应用程序可能冻结,因为EDT与您的其他线程之间存在死锁(在那之前完成)。遵守Oracle Swing线程策略


那么,如何避免例如在用户按下按钮后在EDT上进行冗长的计算呢?选项:

  • 使用SwingWorker。优点:有一种done()您可以使用的方法,一旦工作人员完成,该方法就会在EDT中自动执行。还实现Future接口,因此可以用于返回结果。
  • 您可以只创建自己的文件Runnable并在那里进行计算。
  • 使用Java提供的任何其他并行执行方式。

好吧,以及如何避免不断从外面EDT操纵GUI?

  • SwingUtilities.invokeLater()在那里调用并执行Swing操作。
  • 使用done()如上所述的SwingWorkers 方法。

如果遵循这两个规则,则Swing GUI的状态将更好,并且您可以将更多精力放在应用程序开发上,而不是Swing问题上。