如何以编程方式报告AWT / Swing事件队列长度?

时间:2013-08-09 18:48:41

标签: java swing user-interface event-handling awt

理想情况下,答案将是平台无关的,但特定于平台的,特别是Oracle JVM,也很有用。我正在处理的项目仍在运行版本6 JVM。

特别需要与不时“冻结”的GUI有关。我很清楚在EDT上做GUI工作。该程序在Windows上运行良好,但在迁移到Linux之后,这些“奇怪的”GUI问题开始发生。实际上,在Windows到Linux移动之后,两个应用程序都出现了这个问题。 JVisualVM显示超过1000万个java.awt.EventQueueItem个对象。怀疑是AWT队列的增长速度快于在Linux上提供的速度,因此我们的想法是在应用程序上放置一个AWT队列长度指示器,并在队列增长/缩小时查看它显示的内容。

谷歌搜索了一些this,但它对队列进行了线性扫描。也许有更好的方法?

1 个答案:

答案 0 :(得分:3)

有趣的主题。我已经调查了一下EventQueue代码,虽然我还没有解决你的问题,但我可能会有一些有用的指示:

  1. Oracle的EventQueue实现没有保持大小变量,所以除非你接管EventQueue的完全控制(参见3),否则在使用Oracle时,你不可能比队列的线性扫描做得更好。 JRE。
  2. 你可以写你自己的EventQueue(可能复制粘贴Oracle的实现加上一些调整**将是最简单的)并使用EventQueue.push(EventQueue)来安装你自己的实现。队列中的所有事件都将传输到您的队列,因此您可以在将它们发布到队列时对它们进行计数。不幸的是,这仍然是线性扫描,但至少现在它是独立于平台的。
  3. 或者,您可以在创建原始事件队列后尽快安装自己的EventQueue实现(请参阅2)(在包含main方法的类的开头的静态代码块中执行此操作)。然后,您的实现可以计算发布时的所有事件,并且在您想知道大小时不必扫描队列。你只需要希望没有其他人将你自己的EventQueue推到你的上面;)
  4. **一些调整:我没有试过这个,但我会剥离所有公共/受保护的静态代码(每个引用这些方法/变量的人都使用java.awt.EventQueue,所以你也可以),添加大小变量并使用以下四种方法更新此变量:postEvent(AWTEvent, int)getNextEventPrivate()getNextEvent(int)removeSourceEvent(Object, boolean)

    此修改的一个大问题是EventQueue使用默认可见性(例如,Toolkit.getEventQueue()Component.getAccessControlContext())对AWT方法进行了一些调用,因为您不能调用它们实施将在不同的包中。您必须单独为每个案例找到一种解决方法。