Как связать командную строку?как ускоритель качания для меню помощи? - PullRequest
7 голосов
/ 16 ноября 2011

Стандартная комбинация клавиш для справки: команда - ? на macs. Как я могу связать эту комбинацию клавиш с пунктом меню.

Примечание: поскольку у наших пользователей разные раскладки клавиатуры, я ищу решение, которое не требует знания о том, какая клавиша "?" находится на.

Использование KeyStroke.getKeyStroke(String), что говорит Javadoc;

Parses a string and returns a `KeyStroke`. The string must have the following syntax:

<modifiers>* (<typedID> | <pressedReleasedID>)

modifiers := shift | control | ctrl | meta | alt | button1 | button2 | button3
typedID := typed <typedKey>
typedKey := string of length 1 giving Unicode character.
pressedReleasedID := (pressed | released) key
key := KeyEvent key code name, i.e. the name following "VK_".

У меня есть этот пример кода:

import javax.swing.*;
import java.awt.Dimension;
import java.awt.event.ActionEvent;

public class HelpShortcut extends JFrame {

    public HelpShortcut(){
        // A few keystrokes to experiment with
        //KeyStroke keyStroke = KeyStroke.getKeyStroke("pressed A");    // A simple reference - Works
        //KeyStroke keyStroke = KeyStroke.getKeyStroke("typed ?");      // Works
        KeyStroke keyStroke = KeyStroke.getKeyStroke("meta typed ?");   // What we want - Does not work

        // If we provide an invalid keystroke we get a null back - fail fast
        if (keyStroke==null) throw new RuntimeException("Invalid keystroke");

        // Create a simple menuItem linked to our action with the keystroke as accelerator
        JMenuItem helpMenuItem = new JMenuItem(new HelpAction());
        helpMenuItem.setAccelerator(keyStroke);

        // Install the menubar with a help menu
        JMenuBar mainMenu = new JMenuBar();
        JMenu helpMenu = new JMenu("Help");
        helpMenu.add(helpMenuItem);
        mainMenu.add(helpMenu);

        setJMenuBar(mainMenu);
    }

    // Scaffolding
    public static void main(String[] pArgs) {
        HelpShortcut helpShortcut= new HelpShortcut();
        helpShortcut.setLocationRelativeTo(null);
        helpShortcut.setSize(new Dimension(100, 162));
        helpShortcut.setVisible(true);
    }

    private class HelpAction extends AbstractAction {

        public HelpAction() {
            putValue(Action.NAME,"Help me!");

        }

        @Override
        public void actionPerformed(final ActionEvent pActionEvent) {
            JOptionPane.showMessageDialog(HelpShortcut.this,"You should ask StackOverflow!");
        }

    }
}

Ответы [ 3 ]

6 голосов
/ 16 ноября 2011

На моей клавиатуре "?"находится над клавишей «/», поэтому вы также можете использовать клавишу Shift для ввода «?».Поэтому для привязки нужно использовать:

// KeyStroke keyStroke = KeyStroke.getKeyStroke("meta typed ?");
int modifier = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() 
             + KeyEvent.SHIFT_DOWN_MASK;
KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_SLASH, modifier);
4 голосов
/ 22 ноября 2011

См. KeyEvent API doc - раздел примечаний:

Не всем символам присвоен код ключа.Например, нет кода клавиши для знака вопроса, потому что нет клавиатуры, для которой он появляется на основном уровне.

3 голосов
/ 21 ноября 2011

(что удивительно: мне) :-) Модификаторы привязок идентификаторов ключей "типизированных" не поддерживаются: хотя вы можете создавать и связывать такие в inputMap, они никогда не будут найдены, потому что keyStrokes, сгенерированные для типизированных keyEvents, действительно используют keyChar иигнорировать модификаторы.Это создание происходит в JComponent.processKeyBindings (...)

boolean processKeyBindings(KeyEvent e, boolean pressed) {
  if (!SwingUtilities.isValidKeyEventForKeyBindings(e)) {
      return false;
  }
  // Get the KeyStroke
  KeyStroke ks;

  if (e.getID() == KeyEvent.KEY_TYPED) {
      ks = KeyStroke.getKeyStroke(e.getKeyChar());
  }
  else {
  ks = KeyStroke.getKeyStroke(e.getKeyCode(),e.getModifiers(),
                (pressed ? false:true));
  }

Думая об этом, это может иметь смысл: нажатие / отпускание обрабатывает физические клавиши, в то время как типизированный является окончательным объединенным «выводом» одного илибольше физических ключей.Если для какой-либо комбинации не существует действительного keyChar, событие keyTyped не генерируется.

Основная проблема заключается в хорошо известном сша центризме разработчиков Swing / AWT: они считаются физическими ключами только тех, которые находятся на используемом макете ;-) Нет способа (который я знаю) получить другие ключив макетно-независимой манере.Надеюсь оказаться неправым

...