java.awt.EventQueue.invokeLater explained

2022-09-01 01:03:04

我很好奇为什么我们必须用来控制摆动组件。java.awt.EventQueue.invokeLater

为什么我们不能在普通线程中做到这一点?幕后到底发生了什么?从我注意到的情况来看,如果我有一个,我可以从主线程将可见性设置为true或false而不会得到任何错误,并且它似乎确实有效。那么通过使用我究竟能达到什么目的呢?我也完全知道我可以使用,但正如这里所解释的那样,它们似乎是一回事。JFramejava.awt.EventQueue.invokeLaterSwingUtilities.invokeLater

感谢任何人的解释。希望这是一个有效的问题。

编辑:回答wumpz问题我们可以创建一个jframe

JFrame frame = new JFrame("Hello world");
frame.setSize(new Dimension(300, 300));
frame.setPreferredSize(new Dimension(300, 300));
frame.setMaximumSize(new Dimension(300, 300));
frame.setMinimumSize(new Dimension(300, 300));
frame.setVisible(true);
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

在同一线程上创建它执行以下操作。

for (int i = 0; i < 34; i++)
{
    System.out.println("Main thread setting to "+(!frame.isVisible()));
    frame.setVisible(!frame.isVisible());
}

而且没有抱怨。


答案 1

完整的 Swing 处理在名为 EDT(事件分派线程)的线程中完成。因此,如果您要在此线程中计算一些持久的计算,则会阻止 GUI。

此处的方法是在不同的线程中处理计算,以便 GUI 保持响应。最后,您希望更新 GUI,这必须在 EDT 中完成。现在开始发挥作用。它在 Swings 事件列表的末尾发布一个事件(您的 ),并在处理完所有以前的 GUI 事件后进行处理。EventQueue.invokeLaterRunnable

在这里也可以使用。不同之处在于,在更新 GUI 之前,计算线程会阻塞。因此,很明显,这绝不能从EDT中使用。EventQueue.invokeAndWait

请注意不要从其他线程更新 Swing GUI。在大多数情况下,这会产生一些奇怪的更新/刷新问题。

仍然有Java代码从主线程启动一个简单的JFrame。这可能会导致问题,但 Swing 无法阻止。大多数现代 IDE 现在创建类似这样的东西来启动 GUI:

public static void main(String args[]) {
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new NewJFrame().setVisible(true);
        }
    });
}

答案 2

所有受支持的平台都提供单线程图形库。秋千是跨平台的。因此,应仅在事件调度线程上构造和操作 Swing GUI 对象。

顺便说一句,SwingUtilities.invokeLater()是自1.3版本以来的封面。EventQueue.invokeLater()


推荐