TV.*_*TV. 3 java swing glasspane order-of-execution
(在带有Swing GUI的应用程序中)我想在以循环或方法执行的某些工作中显示GlassPane,这是在单击JButton之后调用的。
例如:(单击按钮后执行的操作)
if (item.equals(button)) {
glassPane.setVisible(true);
someTimeConsumingMethod();
glassPane.setVisible(false);
}
Run Code Online (Sandbox Code Playgroud)
运行此代码会导致在someTimeConsumingMethod()执行期间未显示glassPane-GUI仅冻结了片刻,然后显示结果。删除该循环中的最后一行(glassPane.setVisible(false);)会在方法完成后(GUI冻结时)显示glassPane。
有没有简单的方法可以在GUI冻结之前显示glassPane,还是在这里需要使用一些高级知识?(线程?)
UPDATE1:
我已经根据davidXYZ答案更新了我的代码(有两个更改):
(单击按钮后执行的操作)
if (item.equals(button)) {
glassPane.setVisible(true);
new Thread(new Runnable(){
public void run(){
someTimeConsumingMethod(); // 1st change: running the someTimeConsumingMethod in new Thread
// instead of setting glassPane to visible
}
}).start();
// 2nd change: moved glassPane.setVisible(false); inside the someTimeConsumingMethod(); (placed at the end of it).
}
Run Code Online (Sandbox Code Playgroud)
第一个更改的要点是,在我的GUI线程中运行someTimeConsumingMethod之前,立即在新线程中设置glassPane可见,这是在someTimeConsumingMethod完成后再次显示了glassPane(对此进行了双重检查)。
现在工作正常,谢谢您的所有回答。我一定会检查您提供的所有链接以真正理解线程!
UPDATE2: 更多信息:someTimeConsumingMethod(); 在我的应用程序中,是根据XML数据预装新的Swing组件(由JButtons和JLabel构建的卡,其中需要的JPanel很少,并将它们添加到正确的位置)。
UPDATE3:
我正在尝试使用SwingWorker的invokeLater方法使其工作。现在看起来像这样:
(单击按钮后执行的操作)
if (item.equals(button)) {
glassPane.setVisible(true);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
someTimeConsumingMethod();
glassPane.setVisible(false);
}
});
}
Run Code Online (Sandbox Code Playgroud)
它不能像UPDATE1中的代码那样工作(但仍然可以工作)。问题是:
glassPane加载时不带有.gif动画(文件在自定义glassPane类中设置-适用于UPDATE1代码)
在“工作”过程结束时会有很小的延迟-第一个光标更改为正常状态(从WAIT_CURSOR开始),并且在很短的时间后glassPane消失了。激活/停用时,可通过自定义glassPane类更改光标(使用新的Thread方式不会延迟)。
使用SwingWorker的invokeLater方法是否正确?
编辑:我的错误,我将SwingWorker与SwingUtilities.invokeLater()混淆了。我猜图像问题是由于someTimeCOnsumingMethod启动时GUI冻结所致。
在显示结果之前,GUI只是冻结了片刻。删除该循环中的最后一行(glassPane.setVisible(false);)会在方法完成后(GUI冻结时)显示glassPane。
这是一个常见的问题Event Dispath Thread,当所有事件EDT都Swing GUI在同一时间刷新到时,该方法中的所有操作if (item.equals(button)) {都可以在同一时间完成,
但是您的描述说您在Swing中遇到了Concurency的问题,某些代码阻止了EDT,这是一个很小的延迟,例如Thread.sleep(int)可能导致此问题,不这样做,或者将代码块重定向到Backgroung任务
有没有简单的方法可以在GUI冻结之前显示glassPane,还是在这里需要使用一些高级知识?(线程?)
这个问题是预订示例为什么SwingWorker在那里,或更简单的方法是Runnable#Thread
SwingWorker完全保证在EDT上完成输出的方法
来自Runnable#ThreadSwing GUI的任何输出都应包装在其中invokeLater()
最简单的步骤Jbuttons Action可能是
显示 GlassPane
从启动后台任务SwingWorker(确保通过监听PropertyChangeListener)或调用Runnable#Thread
在这一刻ActionListener执行完成,其余代码被重定向到Backgroung taks
如果任务结束,则隐藏 GlassPane
通过包装setVisible成invokeLater()来创建简单的空隙Runnable#Thread
如果您使用,SwingWorker则可以从中隐藏GlassPaneon正确的事件,PropertyChangeListener也可以使用任何(单独的)空白来隐藏GlassPane
@camickr编写的GlassPane最佳代码,或者基于该代码我的问题
| 归档时间: |
|
| 查看次数: |
1219 次 |
| 最近记录: |