简体   繁体   English

如何在Java中使用SwingWorker?

[英]How do I use SwingWorker in Java?

Related to my previous question: Call repaint from another class in Java? 与我以前的问题有关: 从Java中的另一个类调用重绘?

I'm new to Java and I've had a look at some tutorials on SwingWorker. 我是Java的新手,我看了一些有关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? 任何人都可以就我的代码片段来说明如何使用SwingWorker和/或将我引向一个不错的教程吗? I have looked but I'm not sure I understand yet. 我已经看过了,但不确定自己是否了解。

Generally, SwingWorker is used to perform long-running tasks in Swing. 通常,SwingWorker用于在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 ). 在事件调度线程(EDT)上运行长时间运行的任务可能会导致GUI锁定,因此要做的事情之一是使用SwingUtilities.invokeLaterinvokeAndWait来保持GUI的响应性,从而可以在其他AWT事件发生之前对其他AWT事件进行优先级排序运行所需的任务(以Runnable的形式)。

However, the problem with SwingUtilities is that it didn't allow returning data from the the executed Runnable to the original method. 但是, SwingUtilities的问题在于它不允许将数据从已执行的Runnable返回到原始方法。 This is what SwingWorker was designed to address. 这就是SwingWorker旨在解决的问题。

The Java Tutorial has a section on SwingWorker . Java教程中有关于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. 这是一个示例,其中SwingWorker用于在单独的线程上执行耗时的任务,并在稍后显示答案的消息框。

First off, a class extending SwingWorker will be made: 首先,将创建一个扩展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();
        }
    }
}

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. doInBackgroundget方法的返回类型被指定为SwingWorker的第一种类型,第二种类型是用于publishprocess方法的返回类型,本示例中未使用。

Then, in order to invoke the SwingWorker , the execute method is called. 然后,为了调用SwingWorker ,调用了execute方法。 In this example, we'll hook an ActionListener to a JButton to execute the AnswerWorker : 在此示例中,我们将把ActionListener挂接到JButton以执行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. 可以将上述按钮添加到JFrame ,然后单击以获取消息框。 The following can be used to initialize the GUI for a Swing application: 以下内容可用于初始化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);
}

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. 按钮,一开始什么都不会发生,但是单击“无”按钮将起作用,并表明GUI响应。

And, one second later, the result of the AnswerWorker will appear in the message box. 并且,一秒钟后, AnswerWorker的结果将出现在消息框中。

Agree: 同意:

Running long-running tasks on the Event Dispatch Thread (EDT) can cause the GUI to lock up. 在事件调度线程(EDT)上运行长时间运行的任务可能导致GUI锁定。

Do not agree: 不同意:

so one of the things which were done is to use SwingUtilities.invokeLater and invokeAndWait which keeps the GUI responsive.. 因此,要做的事情之一就是使用SwingUtilities.invokeLater和invokeAndWait来保持GUI响应。

invokeLater still runs the code on the EDT, and can freeze your UI!! invokeLater仍在EDT上运行代码,并且可以冻结您的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. 至少我单击了触发上述代码执行的action的按钮后就无法移动鼠标。 Am I missing something? 我想念什么吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM