在我的代码中,我初始化了一个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 ) {
// ...
}
我的问题是,当我单击运行
dialog.setVisible( false )
的按钮时:对话框消失
框架完全冻结(进度条状态永远不会改变)
在消息“成功登录”之后。出现在控制台上,框架仍然冻结
经过约10秒钟后,框架最终重新粉刷,并且我作为
accountModel.login()
的一部分调用的所有状态消息都出现在其上如何在登录代码运行时使主窗口组件响应?
如您所见,我将整个内容包装在
SwingUtilities.invokeLater()
调用中,但这似乎无济于事。 最佳答案
如您所见,我将整个内容包装在SwingUtilities.invokeLater()调用中,
那就是问题所在。 invokeLater()将代码放在EDT上,这意味着在长时间运行的任务完成执行之前,GUI不能重绘自身对事件的响应。
因此,解决方案是为长时间运行的任务使用单独的Thread
,然后在Thread
中需要更新GUI时使用invokeLater()
。
或者,您也可以使用SwingWorker
为您创建线程,然后可以将代码添加到SwingWorker的done()
方法中以更新GUI。
阅读Swing教程中关于Concurrency的部分,以获取有关Event Dispatch Thread (EDT)
和SwingWorker
的更多信息。
关于java - JDialog在关闭后滞后,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34603679/