代码之家  ›  专栏  ›  技术社区  ›  Xanatos

如何修改swing JMenu项中的快捷键/热键“说明”?

  •  2
  • Xanatos  · 技术社区  · 16 年前

    我们的swing应用程序使用“空格键”作为快捷键。换句话说,如果在应用程序窗口中的任何位置按空格键,它将执行特定的行为。此外,还可以通过使用窗口菜单栏中的JMenuItem来执行相同的行为。

    为了解决这个问题,我们将空格键实现为窗口级的伪快捷键,而没有将其作为快捷键正确地安装在相应的JMenuItem中。它工作得很好,当然除外 JMenuItem上没有任何快捷键“hint”

    但是缺少文本,因为只有在将快捷键作为快捷键安装时,才会将其添加到菜单项中。

    所以我的问题是: 如何修改JMenuItem上的快捷键提示文本,以便自己添加适当的“提示”

    4 回复  |  直到 16 年前
        1
  •  1
  •   Xanatos    16 年前

       @Override public void setAccelerator( KeyStroke keyStroke ) {
          super.setAccelerator( keyStroke );
          getInputMap( WHEN_IN_FOCUSED_WINDOW ).put( keyStroke, "none" );
       }
    

    瞧!非功能快捷键,菜单项上的提示文本保持不变。


    然而,对于我原来的问题,一个更好的解决方案是更改所有快捷键的行为,以便它们 当键盘焦点位于文本组件内时,请勿激发。

    相反,我只需在swing中使用常规快捷键体系结构(即,将其安装在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_);
          }
       }
    

       /**
        * 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 ); } } }

        2
  •  0
  •   akf    16 年前

    考虑到您不接触L&F代码,这是加速器文本的布局。。。

    查看 JMenuItem JMenutItem 对于您的“空格键”项,它将覆盖 setAccelerator 方法来分配加速器击键,但不遍历操作的配置。这应该允许用户界面代码按照您的喜好来布置菜单,而不会在您的用户实际试图在他们的单词之间放置空格时触发讨厌的操作(他们真的需要这样做吗?)。

        3
  •  0
  •   camickr    16 年前

        4
  •  0
  •   xbakesx xbakesx    16 年前

    设置加速器是否会影响您当前实现这一切的方式?如果没有,您可以将加速器设置为空格键。。。我会继续假设你不能那样做。您可以做的另一件事是覆盖JMenuItem上的getAccelerator(),这样您就不必从JMenuItem复制大部分代码(这里没有太多)。

    JMenuItem clickSpace = new JMenuItem("Item With Accelerator Hint -->") {
            @Override
            public KeyStroke getAccelerator()
            {
                return KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0);
            }
        }
    
    推荐文章