3 回答
TA贡献1891条经验 获得超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);
}
}
分享编辑
TA贡献1843条经验 获得超7个赞
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;
}
}
分享编辑
TA贡献1772条经验 获得超8个赞
只需done()
在SwingWorker中重写该方法,然后将调用移至JOptionPane.showMessageDialog(frame, "Message sent", "Success", JOptionPane.INFORMATION_MESSAGE);
该方法中。该方法done()
一旦doInBackground()
完成将被调用,并在EDT上运行。
添加回答
举报