如何在 Java 中使用 SwingWorker?

发布于 2024-07-17 13:27:28 字数 427 浏览 9 评论 0原文

与我之前的问题相关:从 Java 中的另一个类调用重绘?< /a>

我是 Java 新手,我看过一些关于 SwingWorker 的教程。 然而,我不确定如何使用我在上一个问题中给出的示例代码来实现它。

任何人都可以解释如何使用 SwingWorker 来处理我的代码片段和/或为我指出一个不错的教程吗? 我已经看过了,但我不确定我是否理解。

Related to my previous question: Call repaint from another class in Java?

I'm new to Java and I've had a look at some tutorials on SwingWorker. Yet, I'm unsure how to implement it with the example code I gave in the previous question.

Can anyone please explain how to use SwingWorker with regards to my code snippet and/or point me towards a decent tutorial? I have looked but I'm not sure I understand yet.

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

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

发布评论

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

评论(2

分開簡單 2024-07-24 13:27:28

通常,SwingWorker 用于在 Swing 中执行长时间运行的任务。

在事件调度线程 (EDT) 上运行长时间运行的任务可能会导致 GUI 锁定,因此所做的事情之一是使用 SwingUtilities.invokeLaterinvokeAndWait< /a> 保持 GUI 的响应能力,通过在运行所需任务之前优先考虑其他 AWT 事件(以 Runnable 的形式)。

但是,SwingUtilities 的问题是它不允许将数据从执行的 Runnable 返回到原始方法。 这就是 SwingWorker 旨在解决。

Java 教程中有一个关于 SwingWorker 的部分。

下面是一个示例,其中使用 SwingWorker 在单独的线程上执行耗时的任务,并在一秒钟后显示一个包含答案的消息框。

首先,将创建一个扩展 SwingWorker 的类:

class AnswerWorker extends SwingWorker<Integer, Integer>
{
    protected Integer doInBackground() throws Exception
    {
        // Do a time-consuming task.
        Thread.sleep(1000);
        return 42;
    }

    protected void done()
    {
        try
        {
            JOptionPane.showMessageDialog(f, get());
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

doInBackgroundget 方法的返回类型被指定为 code>SwingWorker,第二个类型是用于返回 publishprocess 方法的类型,本示例中未使用这些方法。

然后,为了调用 SwingWorker,将调用 execute 方法。 在此示例中,我们将 ActionListener 挂钩到 JButton 来执行 AnswerWorker

JButton b = new JButton("Answer!");
b.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e)
    {
        new AnswerWorker().execute();
    }
});

上面的按钮可以添加到 JFrame,单击后会出现一个消息框。 以下内容可用于初始化 Swing 应用程序的 GUI:

private void makeGUI()
{
    final JFrame f = new JFrame();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.getContentPane().setLayout(new FlowLayout());

    // include: "class AnswerWorker" code here.
    // include: "JButton" b code here.

    f.getContentPane().add(b);
    f.getContentPane().add(new JButton("Nothing"));
    f.pack();
    f.setVisible(true);
}

应用程序运行后,将出现两个按钮。 其中一张标有“回答!” 和另一个“无”。 当有人点击“回答!”时 按钮,一开始什么也不会发生,但是单击“Nothing”按钮将会起作用并证明 GUI 具有响应能力。

一秒钟后,AnswerWorker 的结果将出现在消息框中。

Generally, SwingWorker is used to perform long-running tasks in Swing.

Running long-running tasks on the Event Dispatch Thread (EDT) can cause the GUI to lock up, so one of the things which were done is to use SwingUtilities.invokeLater and invokeAndWait which keeps the GUI responsive by which prioritizing the other AWT events before running the desired task (in the form of a Runnable).

However, the problem with SwingUtilities is that it didn't allow returning data from the the executed Runnable to the original method. This is what SwingWorker was designed to address.

The Java Tutorial has a section on SwingWorker.

Here's an example where a SwingWorker is used to execute a time-consuming task on a separate thread, and displays a message box a second later with the answer.

First off, a class extending SwingWorker will be made:

class AnswerWorker extends SwingWorker<Integer, Integer>
{
    protected Integer doInBackground() throws Exception
    {
        // Do a time-consuming task.
        Thread.sleep(1000);
        return 42;
    }

    protected void done()
    {
        try
        {
            JOptionPane.showMessageDialog(f, get());
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

The return type of the doInBackground and get methods are specified as the first type of the SwingWorker, and the second type is the type used to return for the publish and process methods, which are not used in this example.

Then, in order to invoke the SwingWorker, the execute method is called. In this example, we'll hook an ActionListener to a JButton to execute the AnswerWorker:

JButton b = new JButton("Answer!");
b.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e)
    {
        new AnswerWorker().execute();
    }
});

The above button can be added to a JFrame, and clicked on to get a message box a second later. The following can be used to initialize the GUI for a Swing application:

private void makeGUI()
{
    final JFrame f = new JFrame();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.getContentPane().setLayout(new FlowLayout());

    // include: "class AnswerWorker" code here.
    // include: "JButton" b code here.

    f.getContentPane().add(b);
    f.getContentPane().add(new JButton("Nothing"));
    f.pack();
    f.setVisible(true);
}

Once the application is run, there will be two buttons. One labeled "Answer!" and another "Nothing". When one clicks on the "Answer!" button, nothing will happen at first, but clicking on the "Nothing" button will work and demonstrate that the GUI is responsive.

And, one second later, the result of the AnswerWorker will appear in the message box.

留一抹残留的笑 2024-07-24 13:27:28

同意:

在事件调度线程 (EDT) 上运行长时间运行的任务可能会导致 GUI 锁定。

不同意:

所以我们所做的事情之一就是使用 SwingUtilities.invokeLater 和 invokeAndWait 来保持 GUI 的响应能力..

仍然在 EDT 上运行代码,并且可以冻结您的 UI! 试试这个:

SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(100000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

至少,一旦我单击触发上述代码的 actionPerformed 的按钮,我就无法移动鼠标。 我错过了什么吗?

Agree:

Running long-running tasks on the Event Dispatch Thread (EDT) can cause the GUI to lock up.

Do not agree:

so one of the things which were done is to use SwingUtilities.invokeLater and invokeAndWait which keeps the GUI responsive..

invokeLater still runs the code on the EDT, and can freeze your UI!! Try this:

SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(100000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

At least I, cannot move my mouse once I click the button which triggers the actionPerformed with the above code. Am I missing something?

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