KeyListener / KeyBindings и порядок добавления компонентов - PullRequest
0 голосов
/ 28 июня 2018

В моей программе в 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");
    }

}

1 Ответ

0 голосов
/ 28 июня 2018

Привязки клавиш работают нормально для меня. Посмотрите на пример Motion Using Key Bindings, который можно найти в Движение с помощью клавиатуры .

Я изменил код:

frame.add( content );
frame.add(left, BorderLayout.NORTH);

до:

frame.setLayout(new GridLayout());
frame.add(left);
frame.add( content );

для лучшей симуляции вашей логики.

Если вам нужна дополнительная помощь, прочитайте комментарий Эндрю выше. Упростите ваш код, чтобы продемонстрировать проблему, чтобы мы могли «легко» протестировать его, скопировав и скомпилировав один исходный файл, так же, как вы можете протестировать код, указанный в ссылке выше.

...