当前位置: 首页 > 知识库问答 >
问题:

当组件隐藏时停止Swing计时器

司寇星海
2023-03-14

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

然而,这会导致问题——特别是,即使在所有窗口都关闭后,它似乎也会阻止应用程序终止,因为实时计时器线程。此外,当看不到动画时,最好避免计时器在隐藏对象上运行的开销。

理想情况下,我希望做到以下几点:

    < li >当组件隐藏时停止计时器 < li >每当组件变得可见时,重新启动计时器

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

共有3个答案

叶稳
2023-03-14

我们这样做:

  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();
        }
     }
  }

}

公冶智刚
2023-03-14

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

因此,如果你的swing计时器持续产生事件,间隔不到一秒,这将阻止应用程序终止。

请看下面的例子。它不会终止,因为该线程即使被标记为守护进程,也一直在向队列中添加事件。如果我们将睡眠时间增加到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();
}
步博厚
2023-03-14

我对你的第一个前提持怀疑态度:这个简单的反例表明,运行的javax.swing.Timer并不排除EXIT_ON_CLOSE。包私有的共享 javax.swing.计时器队列启动一个守护程序线程,该线程允许程序退出。您可能不愿意依赖此实现细节是可以理解的,但是可能值得寻找您的程序无法退出的另一个原因。

如果遵从AncestorListener上的@kleopatra;它应该允许您根据需要控制Timer。组件动画的占空比通常相当轻,通常由渲染主导;当组件不可见时,后者的开销很小。可能值得分析以验证提议的优化是否值得。如果是这样,请考虑使用WindowListener来最小化非活动或图标化窗口中的活动。

附录:一个现已删除的答案建议覆盖< code>setVisible()来调节计时器。虽然表面上很吸引人,但这种方法很脆弱,扩展性很差。监听器方法利用了Swing架构中常用的观察者模式。

 类似资料:
  • 问题内容: 我正在使用Swing 使某个自定义内容在特定时间出现。我希望用户可以选择单击“隐藏”按钮,以关闭该通知并使一个小时后返回。我该如何实现? 问题答案: 有初步的延迟;只需将其设置为即可。调用后一个小时,您将被呼叫。 附录:这是一个按钮示例,该按钮在指定的时间段内隐藏了它的封闭窗口。

  • 问题内容: 我有两个定义如下的实体bean(删除了无关的东西): CriticalItems定义如下: 在我的DAO代码中-我有以下方法: 当我加载MasterItem时,它会正确加载,并且还会按照指示加载CriticalItems Set中的数据。然后,我将此数据发送到我的UI,并获得更新的副本,然后尝试将其保留。用户更新MasterItem对象中的字段,但不触摸CriticalItems Se

  • html正在打印表中的所有API数据。产品和组件当组件为空时,表格不应打印产品。最好的方法是什么?我用的是角度8 产品={"id": 1,"name":"John","组件": [ { "id": 130,"name":"Price", } ] "isSelected": false} 产品={“id”:2,“name”:“name”,“components”:[]}

  • 问题内容: 我已将一个WAR文件部署到Tomcat服务器,该类之一将在启动时调用,然后init()方法将安排一个计时器,每5小时触发一次以执行一些任务。 我的init()代码如下所示: 我的应用程序运行没有问题,但是当我使用 /etc/init.d/tomcat7 stop 关闭Tomcat时,我检查了日志(catalina.out),它具有以下条目: 严重:Web应用程序[/ MyApplica

  • 我的网站上有一个谷歌地图,自12月初以来一直很好用。突然有一天晚上,当我进入站点时,地图默认打开。我关不上。我所有的谷歌地图都是这样的...但几个月来没有人碰过密码?是什么原因造成的? Inspect elements in Firefox告诉我div是隐藏的,但它是相当可见的。 我的控制台显示没有错误。 我知道这是很宽泛的,但它如此奇怪的行为,不可能是由php文件中错误的击键引起的。 好吧。还是

  • 我通过创建固定数量的线程来使用执行器服务来进行HTTP GET数据检索。 当Tomcat停止时,我们会出现以下错误: 严重:web应用程序[/viewer]似乎已启动名为[ThreadExecutor_51616156]的线程,但未能停止该线程。这很可能会造成内存泄漏。 这是真的吗?在没有这些服务错误的情况下,如何正确停止tomcat。