JPanel keylistener - PullRequest
       2

JPanel keylistener

9 голосов
/ 24 января 2011

Я пытаюсь добавить ключевой слушатель, который содержит JTabbedPane.
Он должен переключать вкладки при получении Ctrl + Tab.
Но нажатие клавиш никогда не отправляется Я попытался добавить его на панель и к объекту с вкладками - но безуспешно.

Вот мой код

SwitchTabsListener ctrlTabListener = new SwitchTabsListener(genericTabbedPanel);  
jMainFrame.addKeyListener(ctrlTabListener);  
genericTabbedPanel.addKeyListener(ctrlTabListener);  

Ответы [ 4 ]

15 голосов
/ 24 января 2011

Как правило, ваше ключевое событие не перехватывается правильным компонентом Swing.Вы должны понимать, что первый компонент под курсором получит событие клавиатуры.Если бы вы выбирали кнопку с помощью клавиатуры, именно этот JButton получал бы ключевое событие.

Чтобы убедиться, что вы получаете все эти события, вам не нужно регистрироваться на компонентах, а скорееиспользуя KeyboardFocusManager, который будет получать ключевые события, где бы они ни происходили.

Ваш код тогда требует следующих элементов:

KeyEventDispatcher myKeyEventDispatcher = new DefaultFocusManager();
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(myKeyEventDispatcher);

myKeyEventDispatcher будет принимать вызовыdispatchKeyEvent всякий раз, когда нажимается клавиша, где бы она ни находилась в пользовательском интерфейсе.Таким образом, вы можете убедиться, что ваш код вызывается правильно.

Альтернативный метод регистрации ключевого слушателя потребует от вас использования HierarchyListener для добавления ключевого слушателя.: удалено для каждого компонента свинга, который кажется добавленным / удаленным как дочерний элемент вашего корневого компонента.Это не только громоздко для написания, но и очень трудно отладить и понять.

Именно поэтому я предпочитаю более грубый, но довольно элегантный способ добавления слушателя глобальной клавиши приложения к определенному фокусу клавиатурыменеджер.

3 голосов
/ 24 января 2011

Ctrl+Tab и Ctrl+Shift+Tab позволяют по умолчанию переключаться между вкладками в Windows LookAndFeel :

UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
2 голосов
/ 24 января 2011

Это должно работать. Это, вероятно, не работает для вас, потому что

  1. Вы не выбрали правильное окно.
  2. другой компонент ловит это событие.

Вот код, который я написал для вас.

public class Test {

    public static void main(String[] args) throws InterruptedException {
        JFrame f = new JFrame("aaaa");
        f.setSize(100, 100);
        f.setLocation(100, 100);
        JPanel p = new JPanel();
        f.add(p);

        f.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                System.out.println("pressed");
            }
        });

        p.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                System.out.println("pressed");
            }
        });
        f.setVisible(true);

    }

Работает нормально. Попробуйте поиграть с ним и понять, в чем разница между вашим и моим кодом. Если вы не смогли, отправьте нам большой фрагмент кода.

1 голос
/ 14 июня 2014

Построение из ответа Ридуйдела, вот полный пример.Я не уверен, как определить, происходит ли событие от нажатия клавиши или отпускания клавиши.

import java.awt.KeyboardFocusManager;
import java.awt.KeyEventDispatcher;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;

public class Exit {
    public static void main(String[] args) {
        KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new ExitKeyEventDispatcher());
        JFrame frame = new JFrame();
        frame.setBounds(50, 50, 200, 200);
        frame.setVisible(true);
    }
}
class ExitKeyEventDispatcher implements KeyEventDispatcher {
    public boolean dispatchKeyEvent(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
            System.exit(0);
            e.consume();
        }
        return false;
    }
}
...