SwingWorker in Java [closed]
I did a short example for you hope it helps. Basically a JFrame
witha button is shown:
when the JButton
on the frame is clicked a JDialog
will appear with another JButton
(Send Email) - this would represent the email dialog:
When the JButton
on the emailDialog
is pressed it disposes of the emailDialog
and creates a new JDialog
which will hold the progressbar (or in this case a simple JLabel
):
and then it creates and executes the SwingWorker
to send the email and dispose()
of the JDialog
when its done and show a JOptionPane
message showing success of the sending:
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
output from Substance L&F (in you have got any uncertainties about EDT ust that for testing purposes)
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
and another 200lines about details
output is "correct container created out of EDT"
I'll test that on another L&F, there couls be issue with Nimbus, SystemLokkAndFeel in most cases doesn't care about big mistakes on EDT (very different sensitivity to the EDT), Metal by default haven't any issue on Windows platform and for Java6, then your example works on second bases too
EDIT
Nimbus doeasn't care too
from code
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;
}
}