【问题标题】:How to report AWT/Swing event queue length programmatically?如何以编程方式报告 AWT/Swing 事件队列长度?
【发布时间】:2013-08-11 19:03:54
【问题描述】:

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

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

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

【问题讨论】:

  • 探索,可以拦截事件,如图here
  • 百万setCoalesce(false)?
  • 不。已经想到这一点并扫描了它。没有关闭合并逻辑。

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


【解决方案1】:

有趣的主题。我研究了一下 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()),因为您的实现将在一个不同的包。您必须为每种情况单独找到解决方法。

【讨论】:

  • "copy-pasting" 那是什么??,他可以扩展EventQueu然后push他自己的实现..
  • 问题是你需要修改私有方法,这意味着重新实现它们。由于 java.awt.EventQueue 中的所有代码都调用了它们自己的私有方法,因此您还需要重新实现这些方法。仅当您到达公共或受保护方法时,此重新实现链才会停止。此外,如果链包含从 java.awt 中的其他地方调用的具有默认可见性的方法,则不可能将所有对私有方法的调用重定向到您自己的实现。出于所有实际目的,我认为复制粘贴更好。
猜你喜欢
  • 2012-04-17
  • 2010-11-08
  • 1970-01-01
  • 2018-06-23
  • 1970-01-01
  • 2015-01-09
  • 2010-09-24
  • 2013-02-03
  • 1970-01-01
相关资源
最近更新 更多