我怎样才能修改挥杆JMenu的项目的快捷方式/热键“说明”?
题
我们的摆动应用程序使用“空格”键作为快捷键。换句话说,如果你在任何地方按应用程序窗口内的空格键,它会执行某种行为。更重要的是,这种行为也可以通过在窗口的菜单栏中使用的JMenuItem进行。
要实现这个正常的方法是简单地将“空格键”为“ACCELERATOR_KEY”为相应的JMenuItem,只是让摆动拿剩下的事情。不幸的是,我们不能这样做,因为如果我们把“空格键”为ACCELERATOR_KEY,快捷键触发每次用户点击空格键时,即使在不好的时候,当用户在应用程序窗口内的文本框输入普通的文本一样
为了解决这个问题,我们已经实现了空格键作为一个窗口级的伪快捷键没有相应的JMenuItem正确安装它作为加速器-KEY。它的做工精细,当然除了的JMenuItem中不会对任何快捷键“暗示” 。也就是说,菜单项应该说“空格键”在小灰字母右边的菜单项,使我们的用户可以在没有阅读用户手册“发现”的快捷键。
不过,文本丢失,因为当你安装快捷方式作为加速器-KEY只能被添加到菜单项。
所以我的问题是:如何修改我们的JMenuItem该快捷键提示文本,这样我就可以添加相应的“暗示”自己?这将是很好,如果我能做到这一点,而不必乱在外观和感觉的水平差不多,因为我们的应用是多平台使用多种不同LAFS。
解决方案
感谢您的建议,各位。这个讨论使我一对夫妇的工作,不同的解决方案。
首先,为了解决,而不必实际工作快捷键显示快捷键“暗示”的文字的问题。只需添加快捷键操作/ JMenuItem的正常(这会给你提示文本),然后简单地解除绑定的快捷键右侧已添加之后。一个简单的(但不是唯一的)的方式来做到这一点是创建的JMenuItem的子类,并覆盖一个方法:
@Override public void setAccelerator( KeyStroke keyStroke ) { super.setAccelerator( keyStroke ); getInputMap( WHEN_IN_FOCUSED_WINDOW ).put( keyStroke, "none" ); }
瞧!非功能快捷键,与该菜单项的提示文本仍然完好无损。
有一个更好的解决方案,以我原来的问题,但是,是让他们的当键盘焦点是一个文本组件内不火更改所有快捷键的行为。的据我可以告诉,这是真的在那里同样的空间(未修改)快捷键将与现有的窗口组件的行为冲突的唯一情况。第二个解决方案是多一点的努力,但它是betteron,因为它可以让我删除所有我的其他自定义代码来处理的快捷键,而不在JMenuBar的安装。
相反,我可以只使用在摆动常规快捷键架构,仅有一个单一的小的修改(即,在或的JMenuBar Action对象安装):
此部分是在JMenuItem的的定制子类再次:
/** {@inheritDoc} */ @Override public void setAccelerator( KeyStroke keyStroke ) { super.setAccelerator( keyStroke ); if ( doClickAction_ == null ) { doClickAction_ = new DoClickAction( getActionMap().get( "doClick" ) ); getActionMap().put("doClick", doClickAction_); } }
这是一个新的私有内部类在我的JMenuItem子类:
/** * This action wraps the original "doClick" action for this menu item, * altering it so that it only fires if the keyboard focus is not in any * kind of text area or text field. ** This allows accelerator keys to be added to {@link IMenuItem}s, * but the user can still type those keys into text components without * triggering the accelerator key behaviour. */ private static class DoClickAction extends AbstractAction { // the original action, i.e. that we are wrapping private final Action doClickAction_; DoClickAction( Action doClickAction ) { if ( doClickAction == null ) { throw new IllegalArgumentException(); } doClickAction_ = doClickAction; } @Override public void actionPerformed( ActionEvent e ) { final KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager(); if ( kfm.getFocusOwner() instanceof JTextComponent == false ) { doClickAction_.actionPerformed( e ); } } }
其他提示
考虑到您的要求不要触碰L&F代码,这是在加速器文本被布置...
看着为JMenuItem
代码,似乎你可以创建JMenutItem
为贵“空格键”项,这将覆盖setAccelerator
方法来分配加速器击键的子类,而是通过行动的配置不走。这应该允许UI代码来执行奠定了菜单,只要你喜欢它,没有讨厌的行动及其工作被触发时,您的用户实际上是试图把自己的单词之间的空格(做他们真正需要做的呢?) 。
我不知道,如果文本组件是导致问题的唯一部件。如果是这样,那么也许你可以自定义使用的KeyboardFocusManager确定哪些组件目前已集中行动。如果它是一个文本组件,那么你完全不需要你的行动。
是否设置加速器你当前实现这一切的方式干扰?如果没有,你可以只设置油门空格键......我要继续前进,假设你不能这样做。你可以做的另一件事是在你的JMenuItem覆盖getAccelerator(),所以你不必多数代码从JMenuItem的(不是有很多有)复制。
JMenuItem clickSpace = new JMenuItem("Item With Accelerator Hint -->") {
@Override
public KeyStroke getAccelerator()
{
return KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0);
}
}