当前位置: 首页 > 面试题库 >

Java如何调度KeyEvent?

卢书
2023-03-14
问题内容

我已经阅读了几次有关键绑定的确定教程,但是我的大脑缓存似乎不足以容纳复杂的过程。

我正在调试一个关键的绑定问题(原来我使用的是错误的JComponent.WHEN_*条件),然后我偶然发现javax.swing.KeyboardManager了一个(不幸的)匿名Java工程师为该私有包编写的简洁而有趣的javadoc

我的问题是这样的:除了KeyEventDispatcher一开始就检查的内容之外, 描述是否遗漏和/或错误处理?

KeyboardManager类用于帮助调度WHEN_IN_FOCUSED_WINDOW样式操作的键盘操作。具有其他条件的动作直接在JComponent中处理。

这是我所了解的键盘分配应如何工作的共同含义的描述。

KeyEvent被调度到重点组件。焦点管理器在处理此事件时首先遇到困难。如果焦点管理器不需要它,则JComponent调用super.processKeyEvent(),这使侦听器有机会处理该事件。

如果没有一个侦听器“消费”该事件,则这些快捷键将起作用。这是事情开始变得有趣的地方。首先,使用WHEN_FOCUSED条件定义的KeyStokes
[sic]有机会。如果这些都不想要该事件,那么组件将走动,尽管它是[sic]父级在寻找WHEN_ANCESTOR_OF_FOCUSED_COMPONENT类型的动作。

如果还没有人接受,那么这里就结束了。然后,我们寻找为WHEN_IN_FOCUSED_WINDOW事件注册的组件并将其触发。请注意,如果未找到任何一个,则将事件传递给菜单栏,然后​​让它们进行破解。它们的处理方式不同。

最后,我们检查是否正在查看内部框架。如果我们是,没有人想要该事件,那么我们将移至InternalFrame的创建者,查看是否有人想要该事件(依此类推)。

(更新)如果您曾经对按键绑定指南中的粗体警告有所疑问:

因为搜索组件的顺序是不可预测的,所以请 避免重复的WHEN_IN_FOCUSED_WINDOW绑定!

这是因为KeyboardManager#fireKeyboardAction

     Object tmp = keyMap.get(ks);
     if (tmp == null) {
       // don't do anything
     } else if ( tmp instanceof JComponent) {
           ...
     } else if ( tmp instanceof Vector) { //more than one comp registered for this
         Vector v = (Vector)tmp;
             // There is no well defined order for WHEN_IN_FOCUSED_WINDOW
             // bindings, but we give precedence to those bindings just
             // added. This is done so that JMenus WHEN_IN_FOCUSED_WINDOW
             // bindings are accessed before those of the JRootPane (they
             // both have a WHEN_IN_FOCUSED_WINDOW binding for enter).
             for (int counter = v.size() - 1; counter >= 0; counter--) {
         JComponent c = (JComponent)v.elementAt(counter);
         //System.out.println("Trying collision: " + c + " vector = "+ v.size());
         if ( c.isShowing() && c.isEnabled() ) { // don't want to give these out
             fireBinding(c, ks, e, pressed);
         if (e.isConsumed())
             return true;
         }
     }

因此,搜索顺序实际上是 可预测的 ,但显然取决于此特定实现,因此最好 不要 完全依赖它。使其不可预测。

(Javadoc和代码来自WinXP上的jdk1.6.0_b105。)


问题答案:

我们需要从Component.dispatchEventImpl开始调试。
只需阅读该方法的源注释,就可以对事件在Swing中的流动方式有一个完美的了解(您也可以从EventQueue.pumpEventsForHeirarchy开始上一层)。

为了清楚起见,让我从代码中摘录:

  1. 设置当前事件的时间戳和修饰符。预调度员。在通知AWTEventListener之前,请在此处进行任何必要的重新定位/重新排序。
  2. 允许工具包将此事件传递给AWTEventListeners。
  3. 如果没有人消耗过按键事件,请让KeyboardFocusManager处理它。
  4. 允许输入法处理事件
  5. 交货前对任何特殊事件进行预处理
  6. 传送事件以进行正常处理
  7. 4061116的特殊处理:钩住浏览器以关闭模式对话框。
  8. 允许对等方处理事件。除KeyEvent外,它们将在所有KeyEventPostProcessor之后由对等方处理(请参见DefaultKeyboardFocusManager.dispatchKeyEvent())。

现在,您可以将上述流程与您的描述进行匹配,以确定其正确与否。但是关键是您实际上不应该依赖私有类的javadocs,原因是开发人员通常不关心代码更改时更新私有类的注释,因此文档可能会过时。



 类似资料:
  • 我需要在 Spring boot java 项目中调度多个任务,并通过从数据库中获取任务执行时间的值并在运行时更新程序中的计划约会来执行任务设置。 澄清用例,我有一个 Rest API,它要求我在endpoint上发出 POST 请求,该请求包含在有关此计划的必要信息正文中,例如任务的时间和要执行的作业,发出请求后,任务在我的程序中调度并在指定的时间执行 我研究了一些技术,这些技术提供了解决方案来

  • 我正在使用来调度多个java作业。我想知道在以下情况下会发生什么: 如果我在使用, 运行命令,长首字母延迟,长周期,时间单位 用于调度5个线程池大小为1的作业 p1-5(以分钟为单位的执行间隔) p2-5 p3-5 p4-7 p5-10 5分钟后,p1、p2和p3将激活争用。 将作业分配给一个可用线程使用什么算法?他们会以循环方式分配吗? 现在在第7分钟,假设p1和p2完成,p4变为活动状态,但p

  • 主要内容:1 Java 线程调度程序,2 抢占式调度与时间片调度的区别1 Java 线程调度程序 Java中的线程调度程序是JVM(Java虚拟机)的一部分,它决定应该运行哪个线程。 我们无法保证线程调度程序将会选择哪个线程来运行。 一次只能在一个进程中运行一个线程。线程调度程序主要使用抢占式或时间片调度来调度线程。 2 抢占式调度与时间片调度的区别 在抢占式调度下,最高优先级的任务会一直执行,直到进入等待状态或死机状态或存在更高优先级的任务为止。 在时间分片调度下

  • 我有一个MainClass,一个Worker类和一个Supervisor类。在MainClass中,我创建了10个Worker类和一个Supervisor类,它们在不同的线程中运行。 . . 我不知道如何实现这个,因为每个线程中的条件是相互独立的,所以我不需要同步,所以我不能使用等待通知。

  • 问题内容: 我计划使用Quartz调度程序,因为我阅读了很多好的意见。 我的问题如下:在任何给定时间,系统中都会存在成千上万的触发器。大多数触发器将仅触发一个事件并死亡。另外,很有可能我将不得不在分配许多作业后取消它们(基于新的输入)。 石英可以缩放吗?推荐哪个JobStore?我计划在mysql上使用JDBC。 附加信息 :我的工作将发送电子邮件或通过HTTP发布将数据发布到其他服务(通过WAN

  • 本文向大家介绍iframe如何自动调整高度?相关面试题,主要包含被问及iframe如何自动调整高度?时的应答技巧和注意事项,需要的朋友参考一下 未跨域时,在iframe中利用他的父窗口对象将本页面的滚动高度设置给iframe的height 跨域时,在iframe中将自己的的滚动高设置在本页面内的一个隐藏于父页面不跨域的iframe的hash值, 在隐藏的iframe中将值取出,同未跨域一样设置到要