Java中的SwingWorker

Kar*_*120 -3 java swing multithreading swingworker

我有个问题.

我有一个JFrame.它会创造一个JDialog.

当按下按钮时JDialog,应该处理它并发送电子邮件.与此同时,我需要另一个JDialog不确定的出现JProgressBar.发送电子邮件时,JDialog应该处理(和新的一个),或者它的内容应该更改.

我已经失败了好几个小时了,所以我问enyone他(或她)是否愿意给我写一个能做我想做的伪代码.

只是为了看看SwingWorker课程中应该包含什么(或者如果你觉得它更好的话就使用多线程),何时JDialog应该创建/处理,以及在电子邮件发送中的位置...

我知道我在这里要求一个完整的解决方案,但我已经在dedline并且已经失败了很多次......这是我的最后一招......

Dav*_*amp 12

我做了一个简短的例子,希望它有所帮助.基本上显示了一个带JFrame按钮:

在此输入图像描述

JButton点击框架时,JDialog将出现另一个JButton(发送电子邮件) - 这将代表电子邮件对话框:

在此输入图像描述

JButtonemailDialog按下其配置的emailDialog,并创建一个新的JDialog将举行的进度(或在这种情况下,一个简单的JLabel):

在此输入图像描述

然后它创建并执行SwingWorker发送电子邮件和dispose()JDialog当其完成并显示JOptionPane出发送的成功消息:

在此输入图像描述

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

public class Test {

    public static void main(String[] args) throws Exception {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new Test().createAndShowUI();
            }
        });
    }

    private void createAndShowUI() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        initComponents(frame);
        frame.setPreferredSize(new Dimension(300, 300));//testing purposes
        frame.pack();
        frame.setVisible(true);
    }

    private void initComponents(final JFrame frame) {

        final JDialog emailDialog = new JDialog(frame);
        emailDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        emailDialog.setLayout(new BorderLayout());

        JButton sendMailBtn = new JButton("Send Email");
        sendMailBtn.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                //get content needed for email from old dialog

                //get rid of old dialog
                emailDialog.dispose();

                //create new dialog
                final JDialog emailProgressDialog = new JDialog(frame);
                emailProgressDialog.add(new JLabel("Mail in progress"));
                emailProgressDialog.pack();
                emailProgressDialog.setVisible(true);

                new Worker(emailProgressDialog).execute();

            }
        });

        emailDialog.add(sendMailBtn, BorderLayout.SOUTH);
        emailDialog.pack();

        JButton openDialog = new JButton("Open emailDialog");
        openDialog.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                emailDialog.setVisible(true);
            }
        });

        frame.getContentPane().add(openDialog);

    }
}

class Worker extends SwingWorker<String, Object> {

    private final JDialog dialog;

    Worker(JDialog dialog) {
        this.dialog = dialog;
    }

    @Override
    protected String doInBackground() throws Exception {

        Thread.sleep(2000);//simulate email sending

        return "DONE";
    }

    @Override
    protected void done() {
        super.done();
        dialog.dispose();
        JOptionPane.showMessageDialog(dialog.getOwner(), "Message sent", "Success", JOptionPane.INFORMATION_MESSAGE);

    }
}
Run Code Online (Sandbox Code Playgroud)

  • @DavidKroukamp简单地覆盖SwingWorker中的方法`done()`并将调用移动到`JOptionPane.showMessageDialog(frame,"Message sent","Success",JOptionPane.INFORMATION_MESSAGE);`在该方法中.一旦`doInBackground()`完成并且它在EDT上运行,就会调用`done()`方法. (5认同)
  • 我从未建议不要使用`SwingWorker`.你使用`SwingWorker`但只是不在`doInBackground`方法中执行任何与Swing相关的操作.我在问题的第一条评论中链接了一个例子 (3认同)
  • 你应该为我的公司工作,你看起来很便宜!;-) (2认同)
  • 可能很便宜,但代码不正确.在EDT上没有调用`doInBackground`,因此它不应该调用`JOptionPane.showMessageDialog`或`dialog.dispose`. (2认同)
  • 如果`doInBackground`将在EDT上运行,为什么还要创建一个`SwingWorker` ...`doInBackground`在工作线程上运行,无论你在哪里构建或执行`SwingWorker`(这是一个好的事情).只需查看`execute`方法的源代码即可 (2认同)
  • @DavidKroukamp:Guillaume是对的; 你也可以在`PropertyChangeListener`中监听`SwingWorker.StateValue.DONE`,例如[http://stackoverflow.com/a/7054627/230513]. (2认同)
  • @DavidKroukamp不,不需要它是静态的.这对我的代码片段来说更懒惰了.您确实应该在`process`方法中,在`done`方法中放置涉及EDT的调用,或者通过附加一个也在EDT上调用的侦听器.`SwingWorker`类javadoc也包含一些示例代码 (2认同)