Java Swing-around对话框创建/销毁的多线程问题
可能重复:Java Swing-around对话框创建/销毁的多线程问题,java,multithreading,swing,jdialog,event-dispatch-thread,Java,Multithreading,Swing,Jdialog,Event Dispatch Thread,可能重复: 我有几个课程需要一起学习,但它们不是 首先,我有几个主要问题: public class Main { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { //JFrame dummy for JDialog errors modal = new JFram
我有几个课程需要一起学习,但它们不是 首先,我有几个主要问题:
public class Main
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
//JFrame dummy for JDialog errors
modal = new JFrame();
new PrimaryErrorDialog("Title", "Message", e, false);
JFrame masterWindow = new JFrame();
masterWindow.setVisible();
}
}
}
}
它创建PrimaryErrorDialog类:
private JDialog dialog = this;
private JTextArea text;
private JPanel buttonContainer;
private JButton sendErrorReportT, sendErrorReportF;
public PrimaryErrorDialog(String title, String message,
final Exception error, final boolean exit)
{
super(Main.modal, title, true);
//JButton for sending error report
sendErrorReportT = new JButton("Send Error Report");
sendErrorReportT.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
dialog.dispose();
dialog = new JDialog(Main.modal, "Sending...", true);
Worker thread = new Worker(error);
thread.start();
JProgressBar progress = new JProgressBar();
progress.setIndeterminate(true);
dialog.add(progress);
dialog.pack();
dialog.setVisible(true);
}
});
//JButton for not sending error report
sendErrorReportF = new JButton("Don't send error report");
sendErrorReportF.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
dialog.dispose();
if (exit)
{
System.exit(0);
}
}
});
buttonContainer = new JPanel();
buttonContainer.add(sendErrorReportT);
buttonContainer.add(sendErrorReportF);
add(text);
add(buttonContainer);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
public void cleanUpAndContinue()
{
dialog.dispose();
dialog = new JDialog(Main.modal, "title", true);
dialog.add(/*Jbutton with listener that disposes this dialog*/)
dialog.setVisible(true);
}
它调用扩展线程的thw Worker类:
public class Worker extends Thread
{
Exception e;
public Worker(Exception error)
{
e = error;
}
@Override
public void run()
{
//do something that takes time
PrimaryErrorDialog.cleanUpAndContinue();
}
它返回到PrimaryErrorDialog,然后PrimaryErrorDialog必须通知用户任务已完成,然后终止该对话框
然后我们回到主窗口,主窗口就是在这里创建的
所有这些代码都是在创建masterWindow之前执行的,因为当发生错误时(如果LAF不存在,.properties文件丢失等),会运行此段代码
这就是为什么我创建了虚拟JFrame,以便JDialog可以附加到它,我不想让它成为JFrame
这段代码也会在程序的后面执行,对于“真正的”运行时错误,有些类只是有一些不同的参数和/或构造函数
然而,这不起作用,我已经尝试了无数种方式,我尝试了SwingWorker,似乎没有什么能做我想要的。通常电子邮件代码甚至没有到达,或者程序不等待对话框被处理
我想要什么
错误时有发生。
对话框弹出,告诉我发生了错误,并询问我是否要发送错误报告。
我说否-对话框关闭,如果错误是致命的,则关闭整个程序。
我说是-对话框关闭,新对话框打开时带有未确定的progressbar,而带有stacktrace的电子邮件在后台发送。
发送电子邮件后,progressbar对话框关闭,并打开一个新对话框,告知我的错误报告已发送。
我按下ok,对话框关闭,如果错误是致命的,则关闭整个程序,否则,继续从主类离开的地方
注意:错误可能发生在任何类中,它不仅仅来自Main…- 脏的hack wrap
dialog.setVisible(true)代码>进入
invokeLater()
- 使用
或SwingWorker
代替或普通Runnable#Thread
Thread
- 是否存在您忽略回答的问题,尤其是您先前问题的评论
- Swing Gui不关心线程的输出,因为没有为事件分派线程实现通知程序,您必须通过invokeLater调用它,或者使用
SwingWorker
方法SwingWorkers
,完成
和发布
可以正确通知EDT进度
JDialog
上,但这只是一个概念证明
public class TestSwingWorker {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
final JDialog dialog = new JDialog((Frame)null, "Happy, Happy, Joy, Joy", true);
// This is so I can get my demo to work, you won't need it...
dialog.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
JPanel panel = new JPanel(new GridBagLayout());
panel.setBorder(new EmptyBorder(8, 8, 8, 8));
dialog.setContentPane(panel);
// You'll need you own icon...
JLabel lblIcon = new JLabel(new ImageIcon(getClass().getResource("/waiting-64.png")));
JLabel lblMessage = new JLabel("<html>Hard and work here<br>Please wait...</html>");
final JProgressBar progressBar = new JProgressBar();
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.NORTH;
gbc.weighty = 1;
gbc.insets = new Insets(2, 2, 2, 2);
gbc.gridheight = GridBagConstraints.REMAINDER;
dialog.add(lblIcon, gbc);
gbc.gridheight = 1;
gbc.gridx = 1;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.WEST;
gbc.weighty = 0;
gbc.weightx = 1;
dialog.add(lblMessage, gbc);
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.NORTH;
gbc.weighty = 1;
dialog.add(progressBar, gbc);
dialog.pack();
dialog.setLocationRelativeTo(null);
MyWorker worker = new MyWorker();
// Get notification back from the worker...
worker.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
MyWorker worker = (MyWorker) evt.getSource();
// Progress has been updated
if (evt.getPropertyName().equalsIgnoreCase("progress")) {
progressBar.setValue((Integer)evt.getNewValue());
// The state of the worker has changed...
} else if (evt.getPropertyName().equalsIgnoreCase("state")) {
if (worker.getState().equals(SwingWorker.StateValue.DONE)) {
dialog.dispose();
}
}
}
});
worker.execute();
dialog.setVisible(true);
}
});
}
protected static class MyWorker extends SwingWorker<Object, Object> {
@Override
protected Object doInBackground() throws Exception {
// My long running task...
for (int index = 0; index < 100; index++) {
// Change this to make it faster or slower...
Thread.sleep(250);
setProgress(index);
}
return null;
}
}
}
公共类TestSwingWorker{
公共静态void main(字符串[]args){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}捕获(ClassNotFoundException ex){
}catch(实例化异常){
}捕获(非法访问例外){
}捕获(无支持的LookandFeelexception ex){
}
final JDialog dialog=newjdialog((Frame)null,“Happy,Happy,Joy,Joy”,true);
//这是我可以让我的演示工作,你不会需要它。。。
addWindowListener(新的WindowAdapter(){
@凌驾
公共无效窗口关闭(WindowEvent e){
系统出口(0);
}
});
JPanel panel=newjpanel(newgridbagloayout());
专家组命令(新的清空命令(8,8,8,8));
对话框.setContentPane(面板);
//你需要你自己的图标。。。
JLabel lblIcon=newjlabel(newimageicon(getClass().getResource(“/waiting-64.png”));
JLabel lblMessage=新JLabel(“在这里努力工作,请稍候…”);
最终JProgressBar progressBar=新JProgressBar();
GridBagConstraints gbc=新的GridBagConstraints();
gbc.gridx=0;
gbc.gridy=0;
gbc.anchor=gridbag.NORTH;
gbc.weighty=1;
gbc.插图=新插图(2,2,2,2);
gbc.gridheight=GridBagConstraints.rements;
对话框.添加(lblIcon,gbc);
gbc.gridheight=1;
gbc.gridx=1;
gbc.gridy=0;
gbc.anchor=GridBagConstraints.WEST;
gbc.weighty=0;
gbc.weightx=1;
添加(LBL消息,gbc);
gbc.gridy=1;
gbc.anchor=gridbag.NORTH;
gbc.weighty=1;
添加(进度条,gbc);
dialog.pack();
对话框.setLocationRelativeTo(空);
MyWorker=新的MyWorker();
//从工作人员处获取通知。。。
worker.addPropertyChangeListener(新的PropertyChangeListener(){
@凌驾
公共作废属性更改(属性更改事件evt){
MyWorker=(MyWorker)evt.getSource();
//已更新进展情况
if(evt.getPropertyName().equalsIgnoreCase(“进度”)){
progressBar.setValue((整数)evt.getNewValue());
//工人的状态已更改。。。
}否则,如果(ev)