Java中的SwingWorker

我有个问题。

我有一个JFrame 。 它会创build一个JDialog

当按下JDialog上的button时,它应该被丢弃,并发送一封电子邮件。 同时,我需要另一个JDialog以确定的JProgressBar出现。 当发送电子邮件时, JDialog应该被丢弃(并且新build一个)或者它的内容应该改变。

现在我已经失败了好几个小时了,所以我现在要问的是,如果他(她)能够给我写一个可以做我想做的伪代码的话。

只要看看SwingWorker类中应该包含什么(或者如果你认为它更好,可以使用multithreading),当创build/处理JDialog时,以及在哪里发送邮件…

我知道我在这里要求一个完成的解决scheme,但我已经在一个专业上,已经失败了很多次了…这是我的最后一招…

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

在这里输入图像描述

当框架上的JButton被点击时,一个JDialog将与另一个JButton发送电子邮件 )一起出现 – 这将代表电子邮件对话框

在这里输入图像描述

当按下emailDialog上的JButton时,它会处理emailDialog并创build一个新的JDialog ,它将保存进度条 (或者在这种情况下是一个简单的JLabel ):

在这里输入图像描述

然后创build并执行SwingWorker在完成时发送JDialog的email和dispose() ,并显示一个显示发送成功的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); } } 

@David Kroukamp

来自物质L&F的输出(对于testing目的,您有任何关于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上testing一下,在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; } }