Вопрос по java, swing, keystroke, shortcut – Сочетание клавиш широкого применения - Java Swing

29

Я хотел бы создать комбинацию клавиш для приложения Java Swing. Цикл по всем компонентам и добавление ярлыка для каждого, имеет побочные эффекты, связанные с фокусом, и кажется грубым решением проблемы.

У кого-нибудь есть более чистое решение?

Ваш Ответ

6   ответов
20

ager также является хорошим местом для этой функциональности.

KeyEventDispatcher

1

KeyboardFocusManager keyManager;

keyManager=KeyboardFocusManager.getCurrentKeyboardFocusManager();
keyManager.addKeyEventDispatcher(new KeyEventDispatcher() {

  @Override
  public boolean dispatchKeyEvent(KeyEvent e) {
    if(e.getID()==KeyEvent.KEY_PRESSED && e.getKeyCode()==27){
      System.out.println("Esc");
      return true;
    }
    return false;
  }

});
14

интересующихся (как и я), как использовать KeyEventDispatcher, вот пример, который я собрал. Он использует HashMap для хранения всех глобальных действий, потому что я не люблю большиеif (key == ..) then .. else if (key == ..) then .. else if (key ==..) .. строит.

/** map containing all global actions */
private HashMap<KeyStroke, Action> actionMap = new HashMap<KeyStroke, Action>();

/** call this somewhere in your GUI construction */
private void setup() {
  KeyStroke key1 = KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.CTRL_DOWN_MASK);
  actionMap.put(key1, new AbstractAction("action1") {
    @Override
    public void actionPerformed(ActionEvent e) {
      System.out.println("Ctrl-A pressed: " + e);
    }
  });
  // add more actions..

  KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
  kfm.addKeyEventDispatcher( new KeyEventDispatcher() {

    @Override
    public boolean dispatchKeyEvent(KeyEvent e) {
      KeyStroke keyStroke = KeyStroke.getKeyStrokeForEvent(e);
      if ( actionMap.containsKey(keyStroke) ) {
        final Action a = actionMap.get(keyStroke);
        final ActionEvent ae = new ActionEvent(e.getSource(), e.getID(), null );
        SwingUtilities.invokeLater( new Runnable() {
          @Override
          public void run() {
            a.actionPerformed(ae);
          }
        } ); 
        return true;
      }
      return false;
    }
  });
}

Использование SwingUtils.invokeLater (), возможно, не является необходимым, но, вероятно, будет хорошей идеей не блокировать глобальный цикл обработки событий.

Не самое простое решение, но определенно самое элегантное и надежное.
-1

ActionListener a=new ActionListener(){
   public void actionPerformed(ActionEvent ae)
   {
    // your code
   }
};
getRootPane().registerKeyboardAction(a,KeyStroke.getKeyStroke("ctrl D"),JComponent.WHEN_IN_FOCUSED_WINDOW);

Заменить "Ctrl D" с ярлыком, который вы хотите.

Почему registerKeyboardAction () устарел
нет, это устаревший API (заменен actionMap / inputMap начиная с jdk 1.2 или 1.3 - в далеком прошлом в каменном веке)
@kleopatra Хмм. Спасибо за комментарий. Я хочу знать причину. Я не нашел это!
не совсем понимаю - причина чего?
Пожалуйста, посмотрите javadoc (JComponent.registerKeyboardAction (java.awt.event.ActionListener, java.lang.String, javax.swing.KeyStroke, int)): этот метод теперь устарел, используйте комбинацию getActionMap () и getInputMap () для похожего поведения.
39

JComponent.registerKeyboardAction с условиемWHEN_IN_FOCUSED_WINDOW, Альтернативно используйте:

JComponent.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(keyStroke, command);
JComponent.getActionMap().put(command,action);

как описано вregisterKeyboardAction API документы.

+1 Лучший, самый простой ответ, который я нашел. Я буду голосовать за это x1000
x1001 был бы лучше, таким образом он, по крайней мере, получил бы повышение.
@ Может & APOS; tTellJFrame это неJComponent, Эти методы необходимо вызывать для компонентов в окне верхнего уровня.
Но у JFrame нет метода getInputMap или getActionMap
Для примера первого решения:window.getRootPane().registerKeyboardAction(save.getActionListeners()[0], KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_MASK), JComponent.WHEN_IN_FOCUSED_WINDOW); замещатьsave с именем вашего JButton, иwindow с именем вашего JFrame.
6

вы можете добавить глобальные сочетания клавиш в пункты меню:

    JMenuItem item = new JMenuItem(action);
    KeyStroke key = KeyStroke.getKeyStroke(
        KeyEvent.VK_R, KeyEvent.CTRL_DOWN_MASK);
    item.setAccelerator(key);
    menu.add(item);

Похожие вопросы