首先,感谢您花时间阅读我的问题,我很感激。
以下是我现在所拥有的概述:
我正在编写一个滑块益智游戏,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,如果那是手头的问题。)
答案 0 :(得分:3)
我们可以通过在每个按钮上调用setFocusable(false)
来关注JPanel:
button1.setFocusable(false);
或button2.setFocusable(false);
等
这将允许添加keyListener的JPanel保持焦点。
答案 1 :(得分: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);
}
}