В моей программе в JFrame добавлен компонент JPanel, который управляется слушателем с помощью KeyBindings (изменив его с KeyListeners уже после прочтения о проблемах с фокусировкой). Задача этого приложения - просто перемещать нарисованную фигуру с помощью клавиш со стрелками.
Это работает отлично, пока я не добавлю еще один компонент перед чертежной доской (JPanel с тремя кнопками).
Я протестировал и Keybindings, и KeyListener, и оба метода имеют одну и ту же проблему.
Если я добавляю компоненты после того, как клавиатура для рисования начинает работать снова.
Вот мой класс пользовательского интерфейса, куда я добавляю компоненты.
EDIT: removed uncleaned code
Я бы хотел немного лучше понять Java, поэтому любой ответ очень важен.
Редактировать: я очистил свой код и создал «минимальный» пример проблемы.
Спасибо, Эндрю, за голову.
Программа должна печатать «movingup» в консоли после нажатия стрелки вверх.
Проблема возникает здесь:
container.add(buttons); //after adding this Key Bindings stops working
container.add(board);
И вопрос такой: почему порядок добавления компонентов приводит к тому, что привязки клавиш перестают работать? Если я добавлю кнопки после доска Key Binding работает.
Класс с проблемой (используется для создания фрейма и добавления компонентов)
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.KeyStroke;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.WindowConstants;
public class UserInterface implements Runnable {
private static final String MOVE_UP = "moveUP";
private JFrame frame;
public UserInterface() {
}
@Override
public void run() {
frame = new JFrame("Board");
frame.setPreferredSize(new Dimension(500, 400));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout());
createComponents(frame.getContentPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void createComponents(Container container) {
DrawingBoard board = new DrawingBoard();
container.add(new JButton()); //after adding this figure stops moving - arrow keys doesn't work
container.add(board);
MovingUpwards up = new MovingUpwards(board);
board.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
board.getInputMap().put(KeyStroke.getKeyStroke("UP"), MOVE_UP);
board.getActionMap().put(MOVE_UP, up);
}
public JFrame getFrame() {
return frame;
}
}
Остальные используемые классы для тестирования:
import javax.swing.SwingUtilities;
public class Main {
public static void main (String[] args) {
UserInterface ui = new UserInterface();
SwingUtilities.invokeLater(ui);
}
}
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class DrawingBoard extends JPanel {
public DrawingBoard() {
super.setBackground(Color.WHITE);
}
@Override
protected void paintComponent (Graphics graphics) {
super.paintComponent(graphics);
}
}
import java.awt.Component;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
public class MovingUpwards extends AbstractAction {
private Component component;
public MovingUpwards(Component component) {
this.component = component;
}
@Override
public void actionPerformed(ActionEvent a) {
System.out.println("movingup");
}
}