Форум программистов, компьютерный форум, киберфорум
Drygba
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  

Обработка нажатия клавиш, SWING

Запись от Drygba размещена 16.02.2013 в 17:01
Показов 262 Комментарии 0

Есть два способа обработки нажатия клавиш:
  1. Установка Key Listener'a на компонент
  2. Создание элемента на основе Action класса
Для иллюстрации примеров, создадим окно (JFrame), на него положим панель (JPanel) с кнопками (JButton). Описание основного класса, создание окна и панели - пропустим, если вы начали разбираться с обработкой нажатия клавиш, вы это уже прошли и знаете. Наш пример будет содержать три кнопки с название цвета и менять фон окна при нажатии на них.

Способ 1
Этот метод подходит для новичков, тех кто только начал изучать JAVA. После знакомства со вторым методом, больше не чего хорошего не напишу о нем.
Разберем по порядку что к чему. Обработка нажатия клавиши происходит только для компонента который находится в фокусе (выделен). В фокусе может быть только один элемент, из этого следует что для того чтобы в вашем приложении срабатывали "горячие" клавиши обработчик надо вешать на все элементы у которых может быть фокус.
Для обработки нажатия клавиш на элементе, требуется использовать класс с интерфейсом KeyListener или наследовать от класса KeyAdapter.
В случаем использования интерфейса, нам требуется реализовать три метода:
  1. void keyTyped(KeyEvent e)
  2. void keyPressed(KeyEvent e)
  3. void keyTyped(KeyEvent e)
В случае наследования от класса KeyAdapter, реализуем только тот метод который надо. В примере я пошел по второму варианту, так как использовал только метод keyPressed
Дабы иметь свободный доступ к полям класса PanelButtonSimple, класс, отвечающий за обработку нажатия, сделал внутренним. Далее все просто: получаем код клавиши (e.getKeyCode()) сравниваем его с требуемым нам (KeyEvent.VK_Y) и проверяем нажат ли Ctrl (e.isControlDown()). Если все сходится выполняем действие.
Регистрируем наш класс для всех кнопок и проверяем работу.
Основной класс
Java
1
2
3
4
5
6
7
public class TestAction {
    public static void main (String[] arg){
        Window frame = new Window();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

JFrame
Java
1
2
3
4
5
6
7
8
9
class Window extends JFrame{
    Window(){
        super("Test Action");
        setSize(200,200);
        setLocationRelativeTo(null);
        PanelButtonSimple pbs = new PanelButtonSimple();
        add(pbs);
    }
}

JPanel с кнопками
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/**
 * Панель реализует просту установку "горячих" клавиш для нажатия на кнопки
 */
class PanelButtonSimple extends JPanel{
    JButton blue;
    JButton yellow;
    JButton green;
 
    PanelButtonSimple(){
        blue = new JButton("Blue");
        blue.addKeyListener(new KeyActionSimle());//наш обработчик
        blue.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                setBackground(Color.BLUE);
            }
        });
 
        yellow = new JButton("Yellow");
        yellow.addKeyListener(new KeyActionSimle());//наш обработчик
        yellow.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                setBackground(Color.YELLOW);
            }
        });
 
        green = new JButton("Green");
        green.addKeyListener(new KeyActionSimle());//наш обработчик
        green.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                setBackground(Color.GREEN);
            }
        });
        add(blue);
        add(yellow);
        add(green);
          }
 
    /**
     * Внутренний класс который обрабатывает нажатие клавиш
     */
    class KeyActionSimle extends KeyAdapter{
        @Override
        public void keyPressed(KeyEvent e) {
            //обработчик нажатия на кнопки (ctrl+Y/ctrl+G/ctrl+B)
            if (e.getKeyCode() == KeyEvent.VK_Y && e.isControlDown()) {
                yellow.doClick();//нажатие клавиши
                //или  setBackground(Color.YELLOW); 
            }
            else if (e.getKeyCode() == KeyEvent.VK_G && e.isControlDown()) {
                green.doClick();
            }
            else if (e.getKeyCode() == KeyEvent.VK_B && e.isControlDown()) {
                blue.doClick();
            }
        }
    }
}



Способ 2
Второй метод использует наследника класс AbstractAction. Кто хочет почитать о нем, идут за официальной документацией. Много о нем не расскажу, сам только начал знакомится с ним. Покажу только как с ним работать в нашем примере.
Наш класс ActionButton (наследник AbstractAction) делает две вещи задает название для кнопки и действие при нажатии. При наследовании от AbstractAction, обязательно требуется переопределить метод public void actionPerformed(ActionEvent e).
Когда создается кнопка на основе класса Action, данные для кнопки (иконка, название, всплывающая подсказка, действие...) берутся и класса Action. По этому при реализации своего класса Action учитывайте эту особенность.
В нашем случае нам понадобится - название кнопки и цвет на который будет меняться фон.
Конструктор нашего Action класса:
Java
1
2
3
4
ActionButton(String name, Color c){
            putValue(Action.NAME, name);//аргумент name используем для имени кнопки
            putValue("color", c);// аргумент с используем для установки цвета
}
Обработчик нажатия на кнопку
Java
1
2
3
public void actionPerformed(ActionEvent e) {
            setBackground((Color)getValue("color"));
}
Создание кнопки на основе Action
Java
1
2
ActionButton blueAction = new ActionButton("Blue", Color.BLUE);
new JButton(blueAction)
Подготовка на этом завершена.
Теперь требуется все это связать в одну композицию.
1. Создаем экземпляр класса InputMap на основе нашей панели (на которой кнопки)
Java
1
InputMap imap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
Аргумент WHEN_ANCESTOR_OF_FOCUSED_COMPONENT - указывает что обрабатываться будут все элементы на панели.
2. Добавить в созданный InputMap комбинации клавиш при которых будет срабатывать то или иное действие, и привязать к комбинации метку
Java
1
imap.put(KeyStroke.getKeyStroke("ctrl B"), "panel.blue");
KeyStroke.getKeyStroke - поддерживает несколько вариантов вызова: просто в текстовом виде или значение кнопки. Можно было написать так:
Java
1
imap.put(KeyStroke.getKeyStroke(KeyEvent.VK_B,KeyEvent.CTRL_DOWN_MASK), "panel.blue");
3. Создать ActionMap на основе нашей панели
Java
1
ActionMap amap = getActionMap();
4. Связать полученные InputMap и ActionMap, для этого в ActionMap добавляются метки из InputMap и привязываются к ним созданные экземпляры класса Action
imap.put(KeyStroke.getKeyStroke(KeyEvent .VK_B,KeyEvent.CTRL_DOWN_MASK), "panel.blue");
imap.put(KeyStroke.getKeyStroke("ctrl Y"), "panel.yellow");
imap.put(KeyStroke.getKeyStroke("ctrl G"), "panel.green");

amap.put("panel.blue", blueAction);
amap.put("panel.yellow", yellowAction);
amap.put("panel.green", greenAction);
Все. На этом установка и настройка "горячих" клавиш закончена. С непривычки второй метод показался не понятным и сложным, но пока все это писал разобрался, не чего сложного или не понятного тут нет.


JFrame
Java
1
2
3
4
5
6
7
8
9
class Window extends JFrame{
    Window(){
        super("Test Action");
        setSize(200,200);
        setLocationRelativeTo(null);
        PanelButton pb = new PanelButton();
        add(pb);
    }
}

JPanel с кнопками
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class PanelButton extends JPanel{
    PanelButton(){
        ActionButton blueAction = new ActionButton("Blue", Color.BLUE);
        ActionButton yellowAction = new ActionButton("Yellow", Color.YELLOW);
        ActionButton greenAction = new ActionButton("Green", Color.GREEN);
        add(new JButton(blueAction));
        add(new JButton(yellowAction));
        add(new JButton(greenAction));
 
        InputMap imap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
        imap.put(KeyStroke.getKeyStroke("ctrl B"), "panel.blue");
        imap.put(KeyStroke.getKeyStroke("ctrl Y"), "panel.yellow");
        imap.put(KeyStroke.getKeyStroke("ctrl G"), "panel.green");
 
        ActionMap amap = getActionMap();
        amap.put("panel.blue", blueAction);
        amap.put("panel.yellow", yellowAction);
        amap.put("panel.green", greenAction);
    }
 
    class ActionButton extends AbstractAction{
        ActionButton(String name, Color c){
            putValue(Action.NAME, name);
            putValue("color", c);
        }
        @Override
        public void actionPerformed(ActionEvent e) {
            setBackground((Color)getValue("color"));
        }
    }
}

п.с. Все это писалось в больше степени для себя, дабы как то закрепить и упорядочить прочитанное. Все это хорошо описано у Хорстманна.
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 0
Комментарии
 
Новые блоги и статьи
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru