【问题标题】:Java: GUIs must be initialized in the EDT thread?Java:必须在 EDT 线程中初始化 GUI?
【发布时间】:2010-10-09 02:22:00
【问题描述】:

我是杰森。我对 Substance 的外观和感觉有一点问题 (https://substance.dev.java.net/)。

我的问题更笼统。我已经写好了我的 GUI,它工作正常,但是当我使用 Substance Look-and-feel 时,它需要在 EDT 线程(事件调度线程或其他东西)中进行所有 GUI 初始化。

现在我正在使用 com.sun.java.swing.plaf.windows.WindowsLookAndFeel(不确定我是否拼写正确),它不需要任何这类东西。

所以我通过调用 SwingUtilities.invokeLater() 将主初始化放入 EDT。这使它工作。但是,该程序在执行期间还会生成其他几个窗口。现在我有这样的代码:

SomeNewWindow window = new SomeNewWindow();
// ... some bs emitted
window.doStuff();

这段代码运行良好,因为在调用 window.doStuff() 时,它已经被初始化了。但是 Substance 要求我做这样的事情:

SwingUtilities.invokeLater(new Runnable(){
public void run(){
SomeNewWindow window = new SomeNewWindow();
}});
// ... bs emitted
window.doStuff();

这里有时会抛出 NullPointerException,因为 window.doStuff() 被调用时没有初始化窗口。我无法将 window.doStuff() 放入 EDT 线程,因为它通常需要几秒钟才能返回并且会挂起 GUI。

我尝试在调用 EDT 线程后立即放置 Thread.sleep(1000),因为那时它可能已初始化。但这似乎很尴尬。我只需要一种方法让主线程“知道” SomeNewWindow 初始化何时返回,这样它就可以继续运行而不必担心 NullPointerException。

提前致谢。

【问题讨论】:

    标签: java multithreading user-interface swing look-and-feel


    【解决方案1】:

    为什么不能将 doStuff() 调用移到 invokeLater 回调中?

    SwingUtilities.invokeLater(new Runnable(){
        public void run(){
             SomeNewWindow window = new SomeNewWindow();
             window.doStuff();
        }
    });
    

    如果上述方法不可行,我会使用 invokeAndWait() 而不是 invokeLater(),正如 Paul Tomblin 已经建议的那样。

    【讨论】:

    • 不会,因为 window.doStuff 通常需要几秒钟或几分钟。我尝试这样做,然后窗口在那段时间变得透明。
    【解决方案2】:

    Egwor 建议改用CountDownLatch。绝对看起来它会简化情况。


    这是condition variables 的工作。

    基本上,在 run() 中,锁定锁,构造一些新窗口并发出条件信号(并解锁锁)。 “同时”,在另一个线程中,做你的其他“bs”,锁定锁;如果窗口为空,则在条件变量上等待();解锁锁;窗口.doStuff();

    【讨论】:

    • 我认为倒计时锁可能更好,不是吗?
    • 也许吧。我不知道倒计时锁是什么:)
    【解决方案3】:

    您可以从invokeLater 切换到invokeAndWait,它会一直等到创建窗口。这有点俗气,但还不如睡觉。

    【讨论】:

      【解决方案4】:

      我认为解决此问题的标准方法是让您的 EDT 成为您启动其他工作线程的“基础线程”。

      另一种方法是使用 volatile 标志,初始化程序完成后可以设置该标志,以便其他线程可以在循环中检查它并在设置标志后对新窗口采取行动。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-25
        • 1970-01-01
        • 2017-02-02
        • 2016-09-14
        • 2013-01-03
        相关资源
        最近更新 更多