Java 隐藏组件时停止摆动计时器
我有一个Swing计时器(),用于在自定义Swing组件中执行一些动画 但是,这会导致问题,尤其是在所有窗口关闭后,由于实时计时器线程的原因,它似乎会阻止应用程序终止。另外,当看不到动画时,避免在隐藏对象上运行计时器的开销也很好 理想情况下,我想做以下工作:Java 隐藏组件时停止摆动计时器,java,swing,animation,timer,Java,Swing,Animation,Timer,我有一个Swing计时器(),用于在自定义Swing组件中执行一些动画 但是,这会导致问题,尤其是在所有窗口关闭后,由于实时计时器线程的原因,它似乎会阻止应用程序终止。另外,当看不到动画时,避免在隐藏对象上运行计时器的开销也很好 理想情况下,我想做以下工作: 隐藏组件时停止计时器 每当零部件可见时,再次开始计时 这是否可能(当然是以线程安全的方式!)我怀疑您的第一个前提:这个简单的例子表明运行javax.swing.Timer并不排除关闭时退出。包private,sharedjavax.sw
- 隐藏组件时停止计时器
- 每当零部件可见时,再次开始计时
这是否可能(当然是以线程安全的方式!)我怀疑您的第一个前提:这个简单的例子表明运行
javax.swing.Timer
并不排除关闭时退出。包private,sharedjavax.swing.TimerQueue
启动一个守护进程线程,该线程允许。您可能不愿意依赖这个实现细节,这是可以理解的,但是,寻找程序无法退出的另一个原因可能是值得的
如果推迟到@kleopatra onAncestorListener
;它应该允许您根据需要控制计时器。组件动画的占空比通常相当轻,并且通常由渲染控制;当组件不可见时,后者的开销很小。为了验证所提出的优化是否值得付出努力,可能需要对其进行分析。如果是,请考虑<代码> 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,它将不起作用。