Каким образом компонент Swing просматривает свою ActionMap из своего inputMap, используя промежуточную ссылку Object - PullRequest
2 голосов
/ 22 апреля 2011

Я читал о регистрации объектов «Действие» с несколькими компонентами, и я натолкнулся на рецепт регистрации (привязки) объекта Действие к объекту Нажатие клавиши .

В погоне я наткнулся на этот кусок кода:

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, поддерживаемую компонентом.

Теперь я сомневаюсь, что, если я предполагаю, что семантика сопоставления нажатия клавиши с объектами действия выполняется с использованием подобия ссылки на промежуточный объект, находящейся на этих двух картах, то где гарантия того, что это равенство всегда будет выполняться, если ссылка на объект, которую я использовал, действительно не определяет правильное понятие равенства (или хэш-код).

Например, в моем примере я присоединяю нажатие клавиши с экземпляром String "panel.yellow" в одном из InputMaps, затем я пытаюсь присоединить объект действия с тем же String "panel.yellow" в ActionMap панели. Теперь теоретически JVM не гарантирует, что оба этих экземпляра String (которые я жестко закодировал) будут ссылаться на один и тот же объект String! И что еще хуже, если JVM не предоставляет понятие равенства содержимого для строк, то нет никакого способа, мой объект действия может быть успешно сопоставлен с моим нажатием клавиши. Это так же верно для любого объекта, который я могу использовать для промежуточного связывания нажатия клавиши с объектами действия, и для которого я не определил никакого понятия равенства (или хэш-кода), кроме ссылочного равенства, которое определяет класс Object.

Может кто-нибудь уточнить, пожалуйста.

Avid

Ответы [ 2 ]

1 голос
/ 22 апреля 2011

Строки интернированы по умолчанию, поэтому они будут одним и тем же объектом.См. Метод String.intern () для получения дополнительной информации.

Но если вы действительно обеспокоены этим, то простое решение состоит в использовании одной и той же ссылки на объект в InputMap и ActionMap.

ПроверкаПример кода из Связывания клавиш , который показывает, как я это делаю.

1 голос
/ 22 апреля 2011

Вы правы, что обе строки не могут быть одним и тем же объектом, но вы можете проверить равенство, используя метод equals(...), который, вероятно, будет использоваться для сопоставления вашего действия с нажатием клавиши.

Обратите внимание, что кроме hashCode каждый объект также предоставляет метод equals(...), который может быть таким же, как == для произвольных объектов, но String переопределяет его для проверок на равенство содержимого (что вы также сделаете, еслипереопределить этот метод для пользовательских объектов).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...