Java: JPanel не может получать ключевые события после нажатия кнопки (у которой нет зарегистрированного прослушивателя событий)? - PullRequest
4 голосов
/ 24 декабря 2011

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

Вот обзор того, что я получил сейчас:

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

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

У меня такой вопрос: я знаю, что это довольно расплывчато, но звучит ли это для всех как проблема Java, или это звучит так, будто мой неисправный код стоит за всем этим?

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

Опять же, спасибо, что нашли время, чтобы просмотреть это.

@ trashgod: да, конечно.

public class Test2 extends JPanel{
JButton a = new JButton("A");

Test2(){
    setFocusable(true);
    // Set layout to grid layout
    setLayout(new GridLayout(3, 3));
    // Add button
    //a.setEnabled(false);
    add(a);

    // Register key event which shifts it to the next cell when the right arrow is pressed
    addKeyListener(new KeyAdapter(){
        public void keyPressed(KeyEvent e){
            if (e.getKeyCode() == KeyEvent.VK_LEFT) {
                remove(a);
                JButton b = new JButton("B");
                //b.setEnabled(false);
                add(b);
                add(a);
                validate();

            }
        }
    });
}

}

Функция фрагмента кода: JPanel получает ключевое событие, если быть точным, клавишу со стрелкой влево, удаляет кнопку «a» и добавляет новую кнопку «b», за которой следует кнопка «a» каждый раз. Однако, если вы попытаетесь запустить программу, после нажатия на кнопку она просто перестанет слушать ключевые события.

Я только что подумал, может ли это иметь какое-то отношение к потерянному фокусу в JPanel? Если да, на какие конкретные методы следует обратить внимание, чтобы восстановить потерянный фокус?

Спасибо!

(кстати, комментарии setEnabled - это моя попытка решить эту проблему, просто отключив кнопку, но она по-прежнему не объясняет, как восстановить потерянный фокус на JPanel, если это проблема под рукой.)

Ответы [ 2 ]

3 голосов
/ 01 сентября 2014

Мы можем сохранить фокус на JPanel, просто позвонив setFocusable(false) на каждую кнопку:

button1.setFocusable(false); или button2.setFocusable(false);

и т. Д.

Это позволитJPanel, куда добавляются keyListener, чтобы сохранить фокус.

2 голосов
/ 24 декабря 2011

не все ключи доступны для KeyListener, часть из них регистрируется как встроенные ярлыки для JComponents, зависит от JComponent's type и используется Look and Feel, если вы хотите прослушивать для Keys с клавиатуры, то вам нужно реализовать KeyBindings , компоненты Swing J предназначены для использования этого слушателя, а не KeyListener

рабочий пример для ключа A

import java.awt.GridLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Test2 extends JPanel {

    private static final long serialVersionUID = 1L;
    private JButton a = new JButton("A");

    public Test2() {
        setFocusable(true);
        setLayout(new GridLayout(3, 3));
        a.setEnabled(false);
        add(a);
        addKeyListener(new KeyAdapter() {

            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_A) {
                    remove(a);
                    JButton b = new JButton("B");
                    add(b);
                    add(a);
                    revalidate();
                    repaint();
                }
            }
        });
    }

    public static void main(String... args) {
        JFrame frame = new JFrame("");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new Test2());
        frame.pack();
        frame.setVisible(true);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...