2

我一直在阅读有关使用多个组件注册“Action”对象的信息,并且遇到了将Action对象注册(绑定)到Keystroke对象的方法。

在追求过程中,我遇到了这段代码:

InputMap imap = panel.getInputMap(JComponent.WHEN_FOCUSED);
imap.put(KeyStroke.getKeyStroke("ctrl Y"), "panel.yellow");
ActionMap amap = panel.getActionMap();
amap.put("panel.yellow", yellowAction)

现在它的工作方式是使用 Action 对象注册击键有一层间接性。首先,您将击键关联到组件的一个输入映射(在我们的示例中,它是对应于 WHEN_FOCUSED 常量的映射)中的某个任意对象,然后您在另一个映射 ActionMap 中注册具有相同引用的操作,该映射由零件。

现在我的疑问是,如果我假设将击键映射到动作对象的语义是通过使用驻留在这两个映射中的中间对象引用的相似性来完成的,那么这种相等性将始终成立的保证在哪里,除非对象我使用的参考确实定义了一个有效的相等概念(或哈希码)。

例如,在我的示例中,我在其中一个 InputMaps 中附加了一个带有字符串“panel.yellow”实例的击键,然后我试图在 Panel 的 ActionMap 中附加一个具有相同字符串“panel.yellow”的动作对象. 现在,理论上,JVM 不能保证这两个 String 实例(我已经硬编码)将引用同一个 String 对象!更糟糕的是,如果 JVM 没有为字符串提供内容相等的概念,那么我的动作对象就无法成功地映射到我的击键。这对于我可以用来将击键与动作对象进行中间绑定的任何对象都是如此,除了 Object 类定义的引用相等之外,我没有定义任何相等(或哈希码)的概念。

任何人都可以澄清这一点。

AVID

4

2 回答 2

1

没错,两个字符串可能不是同一个对象,但是您可以使用该equals(...)方法检查是否相等,该方法可能用于将您的操作映射到击键。

请注意,除了hashCode每个对象还提供了一个equals(...)方法,该方法可能与==任意对象相同,但String会覆盖它以进行内容相等性检查(如果您为自定义对象覆盖该方法,您也可以这样做)。

于 2011-04-22T09:03:01.900 回答
1

默认情况下,字符串是实习的,因此它们将是同一个对象。有关详细信息,请参阅 String.intern() 方法。

但如果您真的对此感到担忧,那么简单的解决方案是在 InputMap 和 ActionMap 中使用相同的对象引用。

查看Key Bindings中的示例代码,它展示了我是如何做到这一点的。

于 2011-04-22T14:58:59.787 回答