Использование связывания клавиш
Я занимаюсь базовым программированием, просто пытаюсь изучить основные принципы связывания клавиш. Все это кажется очень простым, но что-то не так с моей логикой или структурой, которая мешает моему коду исполняться так, как я хочу.
Вот мой код
public class Board {
ButtonListener buttonlistener;
EnterAction enterAction;
public Board(){
JFrame skeleton = new JFrame();
skeleton.setDefaultCloseOperation(EXIT_ON_CLOSE);
skeleton.setVisible(true);
skeleton.setSize(400, 400);
buttonlistener = new ButtonListener();
enterAction = new EnterAction();
JPanel panel = new JPanel();
panel.setBackground(Color.BLACK);
JButton button = new JButton("button");
button.addActionListener(buttonlistener);
panel.add(button);
skeleton.add(panel);
panel.getInputMap().put(KeyStroke.getKeyStroke("s"), "doEnterAction");
panel.getActionMap().put("doEnterAction", enterAction);
}
public class ButtonListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("button pressed");
}
}
public class EnterAction extends AbstractAction{
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("enter pressed");
}
}
public static void main(String[] args){
new Board();
}
Так что все должно быть довольно просто. Как вы можете видеть, я просто пытаюсь заставить его печатать "нажата кнопка ввода" всякий раз, когда вы нажимаете клавишу ввода, но ничего не печатается (если вы не нажмете кнопку, также показанную в коде выше). Кроме того, в eclipse класс EnterAction подчеркнут желтым, я думаю, что он может быть вызван неправильно, но я не знаю, почему это не так.
Любая помощь приветствуется, спасибо.
3 ответа
Непосредственная проблема, которую я вижу, заключается в следующем утверждении
panel.getInputMap().put(KeyStroke.getKeyStroke("s"), "doEnterAction");
KeyStroke.getKeyStroke("s")
собирается вернуться null
, Требования к String
Переданные этому методу очень специфичны и плохо документированы (ИМХО).
Вы могли бы использовать KeyStroke.getKeyStroke("S")
вместо этого, но я предпочитаю использовать KeyStroke.getKeyStroke(KeyEvent.VK_S, 0)
поскольку в заявлении нет шансов на двусмысленность.
Я бы также рекомендовал вам определить границы фокуса для входной карты...
Вместо panel.getInputMap()
попробуйте использовать panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
чтобы гарантировать, что ключевое событие будет запущено, если окно сфокусировано
Взгляни на JComponent#getInputMap
Больше подробностей.
Если вы еще этого не сделали, вам также следует взглянуть на Как использовать привязки клавиш
+ Изменить
panel.getInputMap().put(KeyStroke.getKeyStroke("s"), "doEnterAction");
к
panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("S"), "doEnterAction");
Также
skeleton.setDefaultCloseOperation(EXIT_ON_CLOSE);
параметр должен быть JFrame.EXIT_ON_CLOSE
или просто поставить номер 3
,
Я думаю, что Azad и MadProgrammer верны, мне нужно было сделать еще одно простое изменение в дополнение к тому, что они рекомендовали запустить программу. Я перечислил три элемента для вас в качестве комментария в коде: (скопируйте и вставьте, и все готово).
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class Board {
ButtonListener buttonlistener;
EnterAction enterAction;
public Board() {
JFrame skeleton = new JFrame();
//Change #1 below
skeleton.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
skeleton.setVisible(true);
skeleton.setSize(400, 400);
buttonlistener = new ButtonListener();
enterAction = new EnterAction();
JPanel panel = new JPanel();
panel.setBackground(Color.BLACK);
JButton button = new JButton("button");
button.addActionListener(buttonlistener);
panel.add(button);
skeleton.add(panel);
//Change #2 below
panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
KeyStroke.getKeyStroke("S"), "doEnterAction");
panel.getActionMap().put("doEnterAction", (Action) enterAction);
}
public class ButtonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("button pressed");
}
}
public class EnterAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("enter pressed");
}
}
public static void main(String[] args) {
new Board();
}
//Change #3 below
}
вот скриншот: