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

Gre*_*tes 6 java user-interface swing awt event-handling

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

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

一点谷歌搜索发现了这一点,但它对队列进行了线性扫描.也许有更好的方法?

Jel*_*sen 3

有趣的话题。我已经研究了EventQueue一些代码,虽然我还没有解决你的问题,但我可能有一些有用的指示:

  1. Oracle 的实现EventQueue不保留大小变量,因此除非您完全控制EventQueue(参见图 3),否则在使用 Oracle 的 JRE 时,您不会比对队列进行线性扫描更好。
  2. 您可以编写自己的实现EventQueue(可能复制粘贴 Oracle 的实现加上一些调整**将是最简单的)并用于EventQueue.push(EventQueue)安装您自己的实现。队列中的所有事件都将转移到您的队列中,因此您可以在将它们发布到队列中时对它们进行计数。不幸的是,这仍然是线性扫描,但至少现在它是独立于平台的。
  3. EventQueue或者,您可以在创建原始事件队列后尽快安装您自己的实现(请参阅 2)(在包含 main 方法的类开头的静态代码块中执行此操作)。然后,您的实现可以在发布事件时对所有事件进行计数,并且当您想知道大小时无需扫描队列。你只能希望没有人把他们自己的推到EventQueue你的之上;)

** 一些调整:我还没有尝试过这个,但我会删除所有公共/受保护的静态代码(引用这些方法/变量的每个人都使用java.awt.EventQueue无论如何,你也可以),添加大小变量并在下面更新此变量四种方法:postEvent(AWTEvent, int)getNextEventPrivate()getNextEvent(int)removeSourceEvent(Object, boolean)

此修改的一个大问题是,它对EventQueue具有默认可见性的 AWT 方法(例如Toolkit.getEventQueue()Component.getAccessControlContext())进行了一些调用,但您不允许调用这些方法,因为您的实现将位于不同的包中。您必须针对每种情况单独找到解决方法。