如果添加JButton,swing Java FocusListener和KeyListener将无法工作
我有两个实现KeyListener和FocusListener接口的类。两者都不起作用,但是如果我不通过注释或删除以下内容来添加JButton:add(whiteJButton)
,那么它们就起作用了。有人能给我解释一下为什么会这样吗?提前谢谢
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class JFrames {
public static void main(String[] args) {
JFrame myJFrame = new JFrame("MyJFrame");
myJFrame.setBounds(400, 400, 500, 500);
myJFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyJPanel myJPanel = new MyJPanel();
myJFrame.add(myJPanel);
// Doesn't work
myJFrame.addKeyListener(new MyKeyListener());
// Doesn't work
myJFrame.addFocusListener(new MyFocusListener());
myJFrame.setVisible(true);
}
static class MyJPanel extends JPanel {
public MyJPanel() {
JButton whiteJButton = new JButton("WHITE");
add(whiteJButton);
whiteJButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setBackground(Color.WHITE);
}
});
}
}
}
class MyKeyListener implements KeyListener {
@Override
public void keyTyped(KeyEvent e) {
System.out.println("keyTyped: " + e.getKeyChar());
}
@Override
public void keyPressed(KeyEvent e) {
System.out.println("keyPressed: " + e.getKeyChar());
}
@Override
public void keyReleased(KeyEvent e) {
System.out.println("keyReleased: " + e.getKeyChar());
}
}
class MyFocusListener implements FocusListener {
@Override
public void focusGained(FocusEvent e) {
System.out.println("focusGained");
}
@Override
public void focusLost(FocusEvent e) {
System.out.println("focusLost");
}
}
# 1 楼答案
问题是该按钮从JFrame窃取焦点,从而阻止焦点侦听器工作(焦点已经消失)。如果您确实需要使用KeyListener,那么一些解决方案是很麻烦的,包括使JButton不可聚焦:
whiteJButton.setFocusable(false);
,但是如果您这样做,您需要对添加的所有组件执行此操作。是的,你可以像另一个答案所建议的那样要求关注,但应该是requestFocusInWindw()
,而不是requestFocus()
(许多类似的问题解释了为什么会这样)。如果你这样做了,组件仍然是可聚焦的,那么如果一个组件获得了不好的聚焦,整个事情就会崩溃更好的方法(根据注释)是使用Key Bindings,如果使用正确的InputMap,则不需要焦点。请注意,键绑定是Swing本身为组件捕获击键的方式,所以在Swing通用结构和契约中使用键绑定。密钥绑定的问题是,您必须绑定希望捕获的每个密钥,但您可以使用for循环来帮助实现这一点
另一种解决方案是将KeyEventDispatcher用于键盘焦点管理器:
使用键绑定的示例:
# 2 楼答案
您必须聚焦添加侦听器的对象,尝试将侦听器添加到“myJFrame”。你不能专注于杰帕内尔
您的JPanel可能在开始时不可聚焦,而您的JButton获得了焦点。 因此,您还可以将这些代码添加到“myJPanel”: