Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JDialog在关闭后滞后_Java_Swing_Jdialog_Invokelater - Fatal编程技术网

Java JDialog在关闭后滞后

Java JDialog在关闭后滞后,java,swing,jdialog,invokelater,Java,Swing,Jdialog,Invokelater,在我的代码中,我初始化了一个JDialog: dialog = new JDialog( frame, "Login", true ); dialog.setContentPane( panel ); dialog.setDefaultCloseOperation( JDialog.HIDE_ON_CLOSE ); dialog.setBounds( new Rectangle( 50, 50, 500, 500 ) ); 单击主应用程序中的按钮时,我会显示对话框,然后使用从中获取的数据运行一

在我的代码中,我初始化了一个JDialog:

dialog = new JDialog( frame, "Login", true );
dialog.setContentPane( panel );
dialog.setDefaultCloseOperation( JDialog.HIDE_ON_CLOSE );
dialog.setBounds( new Rectangle( 50, 50, 500, 500 ) );
单击主应用程序中的按钮时,我会显示对话框,然后使用从中获取的数据运行一个昂贵的方法:

dialogWrapper.show(); // Runs dialog.setVisible( true ) directly
LoginCredentials credentials = dialogWrapper.getCredentials(); // Gets data from dialog
try {
    SwingUtilities.invokeLater( new Runnable() {
        @Override
        public void run() {
            progressBar.setIndeterminate( true );
            mainWindow.getFrame().repaint();
            accountModel.login( credentials );
            System.out.println( "Successful login." );
            mainWindow.getFrame().revalidate();
            mainWindow.getFrame().repaint();
            progressBar.setIndeterminate( false );
        }
    } );
} catch ( Exception ex ) {
    // ...
}
我的问题是,只要单击运行
对话框的按钮。setVisible(false)

  • 对话框消失了
  • 帧完全冻结(进度条状态永远不变)
  • 在控制台上出现消息“Successful login.”后,框架仍处于冻结状态
  • 大约过了10秒后,框架终于重新绘制,我调用的所有状态消息(作为
    accountModel.login()的一部分)都出现在框架上
如何使主窗口组件在登录代码运行时响应

如您所见,我将整个过程包装在一个
SwingUtilities.invokeLater()
调用中,但这似乎毫无帮助

如您所见,我将整个过程包装在一个SwingUtilities.invokeLater()调用中

这就是问题所在。invokeLater()将代码放在EDT上,这意味着在长时间运行的任务完成执行之前,GUI无法重新绘制自身的Response to events

因此,解决方案是为长时间运行的任务使用单独的
线程
,然后在
线程
中,当需要更新GUI时,使用
调用器()

或者,您也可以使用
SwingWorker
为您创建线程,然后您可以向SwingWorker的
done()
方法添加代码以更新GUI


阅读Swing教程中关于
事件调度线程(EDT)
SwingWorker

阻止事件调度线程的部分,这将阻止传递给
调用器的任何内容在阻止EDT返回(取消阻止)之前被执行