Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.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 隐藏组件时停止摆动计时器_Java_Swing_Animation_Timer - Fatal编程技术网

Java 隐藏组件时停止摆动计时器

Java 隐藏组件时停止摆动计时器,java,swing,animation,timer,Java,Swing,Animation,Timer,我有一个Swing计时器(),用于在自定义Swing组件中执行一些动画 但是,这会导致问题,尤其是在所有窗口关闭后,由于实时计时器线程的原因,它似乎会阻止应用程序终止。另外,当看不到动画时,避免在隐藏对象上运行计时器的开销也很好 理想情况下,我想做以下工作: 隐藏组件时停止计时器 每当零部件可见时,再次开始计时 这是否可能(当然是以线程安全的方式!)我怀疑您的第一个前提:这个简单的例子表明运行javax.swing.Timer并不排除关闭时退出。包private,sharedjavax.sw

我有一个Swing计时器(),用于在自定义Swing组件中执行一些动画

但是,这会导致问题,尤其是在所有窗口关闭后,由于实时计时器线程的原因,它似乎会阻止应用程序终止。另外,当看不到动画时,避免在隐藏对象上运行计时器的开销也很好

理想情况下,我想做以下工作:

  • 隐藏组件时停止计时器
  • 每当零部件可见时,再次开始计时

这是否可能(当然是以线程安全的方式!)

我怀疑您的第一个前提:这个简单的例子表明运行
javax.swing.Timer
并不排除关闭时退出。包private,shared
javax.swing.TimerQueue
启动一个守护进程线程,该线程允许。您可能不愿意依赖这个实现细节,这是可以理解的,但是,寻找程序无法退出的另一个原因可能是值得的

如果推迟到@kleopatra on
AncestorListener
;它应该允许您根据需要控制
计时器。组件动画的占空比通常相当轻,并且通常由渲染控制;当组件不可见时,后者的开销很小。为了验证所提出的优化是否值得付出努力,可能需要对其进行分析。如果是,请考虑<代码> Windows监听器,以最小化非活动或图标化窗口中的活动。


附录:现在删除的答案建议覆盖
setVisible()
以调节计时器。虽然表面上很吸引人,但这种方法很脆弱,伸缩性很差。侦听器方法利用中常用的。

事件队列应安静一秒钟,以便初始化关机。这是awtauthouthutdown类中的硬编码值

因此,如果swing计时器持续生成事件(相隔不到一秒钟),则会阻止应用程序终止

看看这个例子(如下)。它不会终止,因为线程即使标记为deamon,也会不断向队列添加事件。如果我们把睡眠时间增加到1500秒(1.5秒),它将很快终止

public static void main(String[] args)
{
    Thread thread = new Thread(new Runnable()
    {
        @Override
        public void run()
        {
            while (true)
            {
                // Submit an empty event to the queue
                EventQueue.invokeLater(new Runnable()
                {
                    @Override
                    public void run()
                    {
                    }
                });
                try
                {
                    Thread.sleep(500);
                }
                catch (InterruptedException e)
                {
                    throw new IllegalStateException(e);
                }
            }
        }
    });
    thread.setDaemon(true);
    thread.start();
}
我们这样做:

  private static final class DisplayabilityListener implements HierarchyListener {
  private final JComponent component;
  private final Timer timer;

  private DisplayabilityListener(JComponent component, Timer timer) {
     this.component = component;
     this.timer = timer;
  }

  @Override
  public void hierarchyChanged(HierarchyEvent e) {
     if ((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) > 0) {
        if (component.isDisplayable()) {
           timer.start();
        } else {
           timer.stop();
        }
     }
  }

}

hmm。。ancestorListener有什么问题(这是我的第一个想法)?或者你可以添加一个,然后在它的componentHidden(…)和ComponentShowed(…)中添加timer.start()/stop()methods@GagandeepBalincomponentListener仅是一种属性将Listener更改为单个组件的visible属性,如果f.i.一个祖先被隐藏/显示,这一点不会改变。谢谢,这种方法工作得很好(实际上我使用了一个继承人链接器,以便能够捕捉到其他一些事件,但我认为原理是相同的)。我还认为你对计时器的判断也是正确的,但正如你所说的,最好不要依赖这种行为!作为参考,这里有一个相关函数比较了前面提到的三个侦听器。我会将
if((x&y)>0)
更改为
if((x&y)!=0)
,因为如果
y
设置了其MSB,它将不起作用。