java - 当您添加带有按钮的 JPanel 时,为什么 KeyListener 不会收到事件?
问题描述
我有以下 Java swing 应用程序:
它包括:
- 一个 JFrame(窗口)
- 带有 AWT 按钮(按钮)的 JPanel
- 一个红色的JPanel
- 一个绿色的 JPanel
- 一个实现 KeyListener (KeyboardHandler) 的类
如果我不包括按钮,KeyListener 工作,我按下一个键,我会在输出窗口中看到键码。但是一旦我添加了 Buttons 类,关键事件就不再显示在输出窗口中。
为什么?
主要功能如下:
package testkeyboard;
public class TestKeyboard {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Window w = new Window();
w.setVisible(true);
}
}
窗口类如下:
package testkeyboard;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Window extends JFrame {
Buttons buttons;
JPanel panel1;
JPanel panel2;
public Window() {
buttons = new Buttons();
panel1 = new JPanel();
panel1.setBackground(Color.red);
panel2 = new JPanel();
panel2.setBackground(Color.green);
this.setSize(640, 480);
this.getContentPane().add(buttons, BorderLayout.NORTH);
this.getContentPane().add(panel1, BorderLayout.CENTER);
this.getContentPane().add(panel2, BorderLayout.SOUTH);
this.addKeyListener(new KeyboardHandler());
}
}
实现 KeyListener 的类如下:
package testkeyboard;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class KeyboardHandler implements KeyListener {
@Override
public void keyPressed(KeyEvent event) {
System.out.println("KEYCODE: " + event.getKeyCode());
}
@Override
public void keyReleased(KeyEvent event) {
//printEventInfo("Key Released", event);
}
@Override
public void keyTyped(KeyEvent event) {
//printEventInfo("Key Typed", event);
}
}
带有按钮的类如下:
package testkeyboard;
import java.awt.BasicStroke;
import java.awt.Button;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Line2D;
import javax.swing.JPanel;
public class Buttons extends JPanel implements ActionListener {
private Button button1;
private Button button2;
private Button button3;
public Buttons() {
button1 = new Button("B1");
button2 = new Button("B2");
button3 = new Button("B3");
button1.addActionListener((ActionListener) this);
button2.addActionListener((ActionListener) this);
button3.addActionListener((ActionListener) this);
this.add(button1);
this.add(button2);
this.add(button3);
this.setBackground(Color.blue);
this.setForeground(Color.white);
this.setLayout(new FlowLayout(FlowLayout.LEFT));
}
public void actionPerformed(ActionEvent event) {
Object source = event.getSource();
if (source.equals(button1)) {
System.out.println("BUTTON 1 CLICK");
}
else if (source.equals(button2)) {
System.out.println("BUTTON 2 CLICK");
}
else if (source.equals(button3)) {
System.out.println("BUTTON 3 CLICK");
}
}
}
编辑:问题已被标记为重复,SO 问题指出处理 a KeyListener
in a JPanel
,而这个问题处理 a KeyListener
in a JFrame
。它也缺乏一个完整的例子。
因此,如果它可能对其他人有用,我会包含类代码,包括在这种情况下Window
如何使用:KeyBindings
public class Window extends JFrame {
Buttons buttons;
JPanel panel1;
JPanel panel2;
public Window() {
buttons = new Buttons();
panel1 = new JPanel();
panel1.setBackground(Color.red);
panel2 = new JPanel();
panel2.setBackground(Color.green);
this.setSize(640, 480);
this.getContentPane().add(buttons, BorderLayout.NORTH);
this.getContentPane().add(panel1, BorderLayout.CENTER);
this.getContentPane().add(panel2, BorderLayout.SOUTH);
this.addKeyListener(new KeyboardHandler());
InputMap iMap = ((JComponent)(this.getContentPane())).getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap aMap = ((JComponent)(this.getContentPane())).getActionMap();
iMap.put(KeyStroke.getKeyStroke("F2"), "doSomething");
aMap.put("doSomething", doSomething);
};
Action doSomething = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("actionPerformed!");
}
};
}
解决方案
推荐阅读
- c# - 是否可以在 Xamarin Forms WPF 中创建真正的对话框
- c# - 有没有办法创建一个带有 UWP 扩展的 WinForms 应用程序,而不是相反?
- python - 如何快速将切片从 cuda 张量 wrt 切割成另一个张量值
- c++ - OpenGL:透视分割是如何工作的?
- python - 如何在 python 中将 YAML 拆分为不同的文件?
- linux-kernel - 在本机 ARM 设备上编译 Linux 内核后,加载模块失败
- powershell - 查找数组是否有值,然后从该数组中复制 id
- python - Python 字符串切片教程
- c# - 在 SSIS 中不使用公共数据源创建数据表
- java - Zip 2 different Mono in Spring Webfux