-4

我有个问题。

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

当按下按钮时,JDialog它应该被释放并应该发送一封电子邮件。同时,我需要另一个JDialog出现 indetermined JProgressBar。发送电子邮件时,JDialog应处理(并创建新的电子邮件)或更改其内容。

我已经失败了几个小时了,所以我问任何人他(或她)是否愿意给我写一个伪代码来做我想做的事。

只是为了看看应该在SwingWorker课堂上包含什么(或者如果你认为它更好,可以使用多线程),什么时候JDialog应该创建/处置,以及在哪里粘贴电子邮件发送......

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

4

2 回答 2

12

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

在此处输入图像描述

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

在此处输入图像描述

JButtononemailDialog被按下时,它会处理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);

    }
}
于 2012-09-28T14:43:38.273 回答
4

@大卫克鲁坎普

来自 Substance L&F 的输出(您对用于测试目的的 EDT ust 有任何不确定性)

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,那么您的示例也适用于第二个基础

编辑

Nimbus也不在乎

在此处输入图像描述

从代码

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;
    }
}
于 2012-09-28T16:14:22.650 回答