是否调用Later()

发布于 2025-01-07 17:11:17 字数 2100 浏览 1 评论 0原文

我正在编写一个示例来展示 SwingUtilities.invokeLater() 的用法。我开始意识到我编写的这个简单示例(包括代码)并不能保证 invokeLater() 的使用。我确实遇到过,有时我需要使用 invokeLater() 但我忘记了在何时何地使用。我还知道在非 EDP 线程中我应该使用 invokeLater() 但在我的情况下我似乎不需要它并且它工作得很好。我希望有人告诉我为什么我不需要在这段代码中使用 invokeLater() 。我希望我的展示代码中没有错误。

顺便说一句,我在 Linux 和 Windows 中使用 JDK 1.6 / 1.7。

谢谢。

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class HelloButton {
    public static void main(String[] args) {
        JFrame f = new JFrame();
        f.setLayout(new FlowLayout());
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        JSplitPane pane = new JSplitPane();
        f.add(pane);
        final JLabel clickMessage = new JLabel("No Message at " + System.currentTimeMillis());
        pane.setLeftComponent(clickMessage);
        JButton clickMe = new JButton("Click me");
        clickMe.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                threadedIntensiveProcess(clickMessage);
//                intensiveProcess(clickMessage);
            }
        });
        pane.setRightComponent(clickMe);

        f.pack();
        f.setVisible(true);
    }

    static private void threadedIntensiveProcess(final JLabel label)
    {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("UI Thread : " + SwingUtilities.isEventDispatchThread());
                intensiveProcess(label);
            }
        }).start();
    }

    static private void intensiveProcess(JLabel label)
    {
        label.setText("was clicked at " + System.currentTimeMillis());
        for (int i = 0; i < 3; i++)
        {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
            label.setText("was updated at " + System.currentTimeMillis());
        }
        System.out.println(label.getText());
    }
}

I was writing an example to showcase the usage of SwingUtilities.invokeLater(). I came to realize this simple example (code included) I have written didn't warranty the use of invokeLater(). I do encounter there were times I needed to use invokeLater() but I forgotten where and when I used. I also understand that in a non EDP thread I should use invokeLater() but in my case I don't seem to need that and it worked fine. I was hoping anyone advise me why I don't need to use invokeLater() in this piece of code. I hope there is no bug in my showcase code.

Btw, I am using JDK 1.6 / 1.7 in Linux and Windows.

Thanks.

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class HelloButton {
    public static void main(String[] args) {
        JFrame f = new JFrame();
        f.setLayout(new FlowLayout());
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        JSplitPane pane = new JSplitPane();
        f.add(pane);
        final JLabel clickMessage = new JLabel("No Message at " + System.currentTimeMillis());
        pane.setLeftComponent(clickMessage);
        JButton clickMe = new JButton("Click me");
        clickMe.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                threadedIntensiveProcess(clickMessage);
//                intensiveProcess(clickMessage);
            }
        });
        pane.setRightComponent(clickMe);

        f.pack();
        f.setVisible(true);
    }

    static private void threadedIntensiveProcess(final JLabel label)
    {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("UI Thread : " + SwingUtilities.isEventDispatchThread());
                intensiveProcess(label);
            }
        }).start();
    }

    static private void intensiveProcess(JLabel label)
    {
        label.setText("was clicked at " + System.currentTimeMillis());
        for (int i = 0; i < 3; i++)
        {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
            label.setText("was updated at " + System.currentTimeMillis());
        }
        System.out.println(label.getText());
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无名指的心愿 2025-01-14 17:11:17

在两种情况下您应该使用 invokeLater

  1. 用户界面的创建。
  2. JLabel 的更新。

UI 的整个创建应该在 EDT 中完成。在古代 Swing 时代,据说你可以这样做在主线程中的 showsetVisible(true) 之前进行任何创建,因为到那时不会出现线程问题。由于这是并且曾经令人怀疑现在不鼓励这样做< /a>;它可能会起作用 - 显然,就像你的情况一样 - 但不能保证。

您很幸运,JLabel 中的 setText 在这种情况下表现良好。由于 API 不保证该方法是线程安全的,因此您应该在 EDT 中调用此方法,就像对 Swing 方法的任何其他调用一样。

所以,总而言之:你有一个似乎有效的简单例子 - 因为它很简单而且你很幸运。不要依赖这样的“测试”,而要依赖文档。如果您的展示涉及代码的演示,那么您必须将调用移至 EDT,以免出错。

我不明白为什么您的代码不应该“保证”使用 invokeLater

There are two situations here where you should use invokeLater.

  1. The creation of the UI.
  2. The update of the JLabel.

The whole creation of the UI should be done in the EDT. In ancient Swing times it was said that you could do any creation until show or setVisible(true) in the main thread as no threading issues could arise up to that point. As this is and was doubtful this is now discouraged; it may work -obviously, as in your case- but there is no guarantee.

You are lucky that setText in JLabel behaves well in this context. As it is not guaranteed by the API that the method is threadsafe you should call this method in the EDT like any other call to Swing methods.

So, in conclusion: You have a simple example that seems to work - because it is simple and you are lucky. Don't rely on such "tests" but on the documentation. If your showcase involves the presentation of the code then you have to move the calls to the EDT for not being wrong.

I don't understand why your code shouldn't "warrant" the use of invokeLater.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文