为了账号安全,请及时绑定邮箱和手机立即绑定

Java中的SwingWorker

/ 猿问

Java中的SwingWorker

慕容森 2019-12-06 15:45:17

我有个问题。

我有一个JFrame。它将创建一个JDialog

当按下开按钮时JDialog,应将其丢弃并发送电子邮件。同时,我需要另一个JDialog以不确定的形式出现JProgressBar。发送电子邮件时,JDialog应将其丢弃(并重新创建一封信),或更改其内容。

我现在已经失败了几个小时,所以我问enyone,他(或她)是否足够友善地为我编写一个可以满足我要求的伪代码。

只是为了看看应该在SwingWorker类中包含什么(或者,如果您认为更好的话,可以使用多线程),JDialog应该在何时创建/处置(s)以及在哪里保留发送电子邮件...

我知道我要在这里寻求完整的解决方案,但是我处于底线,已经失败了很多次……这是我的最后选择……


查看完整描述

3 回答

?
万千封印

我做了一个简短的例子,希望对您有所帮助。基本上显示一个JFramewitha按钮:

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

当JButton上emailDialog按下其配置的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);


    }

}

分享编辑


查看完整回答
反对 回复 2019-12-06
?
蓝山帝景

L&F物质的输出(因为您对EDT的不确定性有待测试)


run:

JButton openDialog >>> Is there EDT ??? == true

Worker started >>> Is there EDT ??? == false

waiting 30seconds 

Worker endeded >>> Is there EDT ??? == false

before JOptionPane >>> Is there EDT ??? == false

org.pushingpixels.substance.api.UiThreadingViolationException: 

     Component creation must be done on Event Dispatch Thread

和另外200行有关详细信息


输出是 "correct container created out of EDT"


我将在另一家L&F上进行测试,Nimbus可能存在问题,SystemLokkAndFeel在大多数情况下并不关心EDT上的重大错误(对EDT的敏感性完全不同),默认情况下,Metal在Windows平台上没有任何问题,对于Java6,那么您的示例也可以在第二基础上使用


从代码


import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.Dimension;

import java.awt.Font;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.*;

import javax.swing.plaf.FontUIResource;


public class Test {


    public static void main(String[] args) throws Exception {

        try {

            for (UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {

                if ("Nimbus".equals(info.getName())) {

                    UIManager.setLookAndFeel(info.getClassName());

                    UIManager.getLookAndFeelDefaults().put("nimbusOrange", (new Color(127, 255, 191)));


                    break;

                }

            }

        } catch (ClassNotFoundException ex) {

        } catch (InstantiationException ex) {

        } catch (IllegalAccessException ex) {

        } catch (javax.swing.UnsupportedLookAndFeelException ex) {

        }

        SwingUtilities.invokeLater(new Runnable() {


            @Override

            public void run() {

                /*try {

                    UIManager.setLookAndFeel(

                            "org.pushingpixels.substance.api.skin.SubstanceOfficeBlue2007LookAndFeel");

                    UIManager.getDefaults().put("Button.font", new FontUIResource(new Font("SansSerif", Font.BOLD, 24)));

                    UIManager.put("ComboBox.foreground", Color.green);

                } catch (Exception e) {

                }*/

                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, frame).execute();


            }

        });

        emailDialog.add(sendMailBtn, BorderLayout.SOUTH);

        emailDialog.pack();

        JButton openDialog = new JButton("Open emailDialog");

        openDialog.addActionListener(new ActionListener() {


            @Override

            public void actionPerformed(ActionEvent e) {

                System.out.println("JButton openDialog >>> Is there EDT ??? == " + SwingUtilities.isEventDispatchThread());

                emailDialog.setVisible(true);

            }

        });

        frame.getContentPane().add(openDialog);

    }

}


class Worker extends SwingWorker<String, Object> {


    private final JDialog dialog;

    private final JFrame frame;


    Worker(JDialog dialog, JFrame frame) {

        this.dialog = dialog;

        this.frame = frame;

    }


    @Override

    protected String doInBackground() throws Exception {

        System.out.println("Worker started >>> Is there EDT ??? == " + SwingUtilities.isEventDispatchThread());

        System.out.println("waiting 30seconds ");

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

        System.out.println("Worker endeded >>> Is there EDT ??? == " + SwingUtilities.isEventDispatchThread());

        dialog.dispose();

        System.out.println("before JOptionPane >>> Is there EDT ??? == " + SwingUtilities.isEventDispatchThread());

        JOptionPane.showMessageDialog(frame, "Message sent", "Success", JOptionPane.INFORMATION_MESSAGE);

        System.out.println("before JOptionPane >>> Is there EDT ??? == " + SwingUtilities.isEventDispatchThread());

        return null;

    }

}

分享编辑


查看完整回答
反对 回复 2019-12-06
?
料青山看我应如是

只需done()在SwingWorker中重写该方法,然后将调用移至JOptionPane.showMessageDialog(frame, "Message sent", "Success", JOptionPane.INFORMATION_MESSAGE);该方法中。该方法done()一旦doInBackground()完成将被调用,并在EDT上运行。

查看完整回答
反对 回复 2019-12-06

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信