(在我使用 Swing GUI 的应用程序中)我想在单击 JButton 后调用的循环或方法中执行的某些工作期间显示 GlassPane。
例如:(单击按钮后执行的操作)
if (item.equals(button)) {
glassPane.setVisible(true);
someTimeConsumingMethod();
glassPane.setVisible(false);
}
运行此代码会导致在执行 someTimeConsumingMethod() 期间不显示 glassPane - GUI 会在显示结果之前冻结片刻。删除该循环中的最后一行 (glassPane.setVisible(false);) 会导致在方法完成后显示 glassPane(当 GUI 解冻时)。
有没有一种简单的方法可以在 GUI 冻结之前显示 glassPane,或者我需要在这里使用一些高级知识?(线程?)
更新1:
我已经根据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).
}
第一个更改的要点是,在我的 GUI 线程中运行 someTimeConsumingMethod 之前,在新线程中设置 glassPane 可见在 someTimeConsumingMethod 完成后会显示 glassPane(仔细检查)。
现在它工作正常,谢谢你的所有答案。我一定会检查您提供的所有链接以真正理解线程!
UPDATE2: 更多信息:someTimeConsumingMethod(); 在我的应用程序中,正在根据 XML 数据准备新的 Swing 组件(从 JButtons 和 JLabels 构建的卡片,在需要的地方很少有 JPanel,并将它们添加到正确的位置)。
UPDATE3:
我正在尝试使用 SwingWorker 的 invokeLater 方法使其工作。现在看起来像这样:
(单击按钮后执行的操作)
if (item.equals(button)) {
glassPane.setVisible(true);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
someTimeConsumingMethod();
glassPane.setVisible(false);
}
});
}
它的效果不如UPDATE1中的代码好(但仍然有效)。问题是:
glassPane 加载时没有 .gif 动画(文件在自定义 glassPane 类中设置 - 它适用于UPDATE1代码)
“工作”过程结束时有一点延迟 - 第一个光标变为正常(来自 WAIT_CURSOR),并且在很短的时间后 glassPane 消失。光标在激活/停用时由自定义 glassPane 类更改(使用新线程方式无延迟)。
使用 SwingWorker 的 invokeLater 方法是否正确?
编辑:我的错误,我将 SwingWorker 与 SwingUtilities.invokeLater() 混淆了。我猜图像问题是由于 someTimeCONsumingMethod 启动时 GUI 冻结所致。