Java:JPanel在单击按钮后(没有注册的事件侦听器)无法接收键事件?

问题描述 投票:4回答:2

首先,感谢您抽出宝贵的时间来阅读我的问题,我对此表示赞赏。

这是我现在所拥有的概述:

我正在写一个滑块益智游戏,使用按钮作为网格单元,三乘三。我在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。)

java swing jbutton keylistener clicking
2个回答
2
投票

并非所有键都可用于KeyListener,如果您想从中收听JComponents,则它们的一部分会注册为JComponent's type的内置快捷键,取决于Look and Feel并使用Keys。键盘,那么您必须实现KeyBindings,将Swing JComponents指定为使用此侦听器,而不是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);
    }
}

3
投票

我们可以通过只单击每个按钮上的setFocusable(false)来保持对JPanel的关注:

[button1.setFocusable(false);button2.setFocusable(false);

这将使添加了keyListener的JPanel保持焦点。

© www.soinside.com 2019 - 2024. All rights reserved.