(在我使用Swing GUI的应用程序中)我想在以循环或方法执行的某些工作中显示GlassPane,这是在单击JButton之后调用的。

例如:
(单击按钮后执行的操作)

if (item.equals(button)) {

    glassPane.setVisible(true);

    someTimeConsumingMethod();

    glassPane.setVisible(false);

}

运行此代码会导致在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).

}

第一个更改的要点是,在我的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);
        }
    });

}

作为 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#Thread到Swing GUI的任何输出都应包装在invokeLater()

  • Jbuttons Action最简单的步骤可能是
  • 显示GlassPane
  • SwingWorker启动后台任务(请确保通过PropertyChangeListener监听)或调用Runnable#Thread
  • 在此刻完成ActionListener执行,其余代码重定向到Backgroung taks
  • 如果任务结束,则隐藏GlassPane
  • 通过将setVisible包装到invokeLater()中为Runnable#Thread
  • 创建简单的空隙
    如果您使用SwingWorker,则可以使用
  • ,然后可以在GlassPane中隐藏适当事件时的PropertyChangeListener,也可以使用任何(单独的)空位来隐藏GlassPane

  • GlassPane by @camickr或我的question about based on this code的最佳代码

    10-06 05:01