将 KeyListener 添加到 Jframe 问题
Add KeyListener to Jframe issue
我有一个我在 Netbeans 中制作的 jframe,这个 jframe 被另一个 java class "launched",但对于当前的问题并不重要。重要的是我似乎无法弄清楚如何将我的关键侦听器添加到我的这个 jframe 中。我已经实现了键侦听器,添加了所需的功能(键入键、按下键和释放键)。但我无法弄清楚如何实际 add/initiate 实际的关键侦听器,以使其工作。
截至目前,我已经尝试了两种不同的方法,首先我尝试在代码的开头添加行 addKeylistener(new JFrameList());
,在此处启动实际的 jframe,但这样做是实际的框架甚至不会显示。除此之外,我尝试在另一个函数 callJframFForm()
中添加同一行,该函数在调用 jframe 的同时从另一个 class 调用。但这只是 returns 错误 non-static method addKeyListener(KeyListener) cannot be referenced from a static context
。我不确定还有什么其他方法可以添加关键侦听器,因此我正在寻求一些帮助。
目前我的代码如下所示。
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class JFrameList extends javax.swing.JFrame implements KeyListener{
public static String keyPresCod = "";
public JFrameList() {
initComponents();
addKeyListener(new JFrameList()); //This is where I am currently trying to call from, but frame won't show
}
public static void main(String args[]) {
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new JFrameList().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
// End of variables declaration
static void callJframFForm(){
try {
//This is where I have also tried to add the initialization line
} catch(Exception e) {
e.printStackTrace();
}
}
@Override
public void keyTyped(KeyEvent e) {
int codeFKey = e.getKeyCode();
if (codeFKey == KeyEvent.VK_A) {
System.out.println("Button A clicked");
keyPresCod = "A";
} else if (codeFKey == KeyEvent.VK_B) {
System.out.println("Button B clicked");
keyPresCod = "B";
} else {
System.out.println("Different key pressed");
keyPresCod = "Another key";
}
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
}
问题
addKeyListener(new JFrameList())
这将创建一个新的 JFrameList
对象并使用它的侦听器。这意味着任何击键都存储在新对象的成员中。要查看结果,您必须执行
JFrameList 列表 = new JFrameList();
添加按键监听器(列表);
//使用列表变量访问keyPressed代码
当然这不是您想要的行为。您希望击键存储在当前实例中,而不是新对象中。这意味着你应该做
addKeyListener(this)
尽管您可能注意到侦听器只能工作 "sometimes",或者可能根本不工作,具体取决于您的测试方式。
Swing 使用焦点系统来管理哪些侦听器应该接收事件,并且由于您要将侦听器添加到 JFrame
,侦听器将仅在框架处于焦点时接收事件。
解决方案
你应该use key bindings rather than a key listener.
如果您选择继续使用监听器,您应该将它添加到您的按钮,而不是您的框架:
jButton1.addKeyListener(this);
jButton2.addKeyListener(this);
您可以通过调用 event.getSource()
.
获取事件源(您的按钮),而不是检查事件的键代码
键绑定允许您为组件设置灵活的焦点设置。您需要做的就是访问组件的输入映射:
String actionCommand = "Press Button A";
jButton1.setActionCommand(actionCommand);
jButton1.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("A"), actionCommand);
jButton1.getActionMap(actionCommand, this);
您的 JFrameList
现在应该实施 ActionListener
而不是 KeyListener
,因为它将接收您的事件作为操作:
class JFrameList extends JFrame implements ActionListener {
private JButton jButton1;
public JFrameList() {
jButton1 = new JButton("A");
//set action command, add to input map, add to action map
}
public void actionPerformed(ActionEvent event) {
JButton button = (JButton) event.getSource();
System.out.println(button.getActionCommand() + " was performed.");
}
}
备选
JButton
具有 built-in 助记符处理。可以通过JButton#setMnemonic(int)
指定助记词,其中参数为键码:
jButton1.setMnemonic(KeyEvent.VK_A);
这是在图形界面中处理热键的标准方式。只需按住 Alt 键 (windows),然后按您设置助记符的键即可。
Key Events 只发送给有焦点的组件。您没有 post 整个代码,但我猜焦点在您添加到框架的按钮上,因此该按钮获得 KeyEvent。
不确定您要使用 KeyListener 做什么。您无法通过查看在 KeyEvent 中键入的字符来判断单击了哪个按钮。
如果您想知道点击了哪个按钮,则需要为每个按钮添加一个 ActionListener
。阅读有关 How to Use Buttons 的 Swing 教程部分,了解更多信息和示例。
我有一个我在 Netbeans 中制作的 jframe,这个 jframe 被另一个 java class "launched",但对于当前的问题并不重要。重要的是我似乎无法弄清楚如何将我的关键侦听器添加到我的这个 jframe 中。我已经实现了键侦听器,添加了所需的功能(键入键、按下键和释放键)。但我无法弄清楚如何实际 add/initiate 实际的关键侦听器,以使其工作。
截至目前,我已经尝试了两种不同的方法,首先我尝试在代码的开头添加行 addKeylistener(new JFrameList());
,在此处启动实际的 jframe,但这样做是实际的框架甚至不会显示。除此之外,我尝试在另一个函数 callJframFForm()
中添加同一行,该函数在调用 jframe 的同时从另一个 class 调用。但这只是 returns 错误 non-static method addKeyListener(KeyListener) cannot be referenced from a static context
。我不确定还有什么其他方法可以添加关键侦听器,因此我正在寻求一些帮助。
目前我的代码如下所示。
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class JFrameList extends javax.swing.JFrame implements KeyListener{
public static String keyPresCod = "";
public JFrameList() {
initComponents();
addKeyListener(new JFrameList()); //This is where I am currently trying to call from, but frame won't show
}
public static void main(String args[]) {
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new JFrameList().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
// End of variables declaration
static void callJframFForm(){
try {
//This is where I have also tried to add the initialization line
} catch(Exception e) {
e.printStackTrace();
}
}
@Override
public void keyTyped(KeyEvent e) {
int codeFKey = e.getKeyCode();
if (codeFKey == KeyEvent.VK_A) {
System.out.println("Button A clicked");
keyPresCod = "A";
} else if (codeFKey == KeyEvent.VK_B) {
System.out.println("Button B clicked");
keyPresCod = "B";
} else {
System.out.println("Different key pressed");
keyPresCod = "Another key";
}
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
}
问题
addKeyListener(new JFrameList())
这将创建一个新的 JFrameList
对象并使用它的侦听器。这意味着任何击键都存储在新对象的成员中。要查看结果,您必须执行
JFrameList 列表 = new JFrameList(); 添加按键监听器(列表); //使用列表变量访问keyPressed代码
当然这不是您想要的行为。您希望击键存储在当前实例中,而不是新对象中。这意味着你应该做
addKeyListener(this)
尽管您可能注意到侦听器只能工作 "sometimes",或者可能根本不工作,具体取决于您的测试方式。
Swing 使用焦点系统来管理哪些侦听器应该接收事件,并且由于您要将侦听器添加到 JFrame
,侦听器将仅在框架处于焦点时接收事件。
解决方案
你应该use key bindings rather than a key listener.
如果您选择继续使用监听器,您应该将它添加到您的按钮,而不是您的框架:
jButton1.addKeyListener(this);
jButton2.addKeyListener(this);
您可以通过调用 event.getSource()
.
键绑定允许您为组件设置灵活的焦点设置。您需要做的就是访问组件的输入映射:
String actionCommand = "Press Button A";
jButton1.setActionCommand(actionCommand);
jButton1.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("A"), actionCommand);
jButton1.getActionMap(actionCommand, this);
您的 JFrameList
现在应该实施 ActionListener
而不是 KeyListener
,因为它将接收您的事件作为操作:
class JFrameList extends JFrame implements ActionListener {
private JButton jButton1;
public JFrameList() {
jButton1 = new JButton("A");
//set action command, add to input map, add to action map
}
public void actionPerformed(ActionEvent event) {
JButton button = (JButton) event.getSource();
System.out.println(button.getActionCommand() + " was performed.");
}
}
备选
JButton
具有 built-in 助记符处理。可以通过JButton#setMnemonic(int)
指定助记词,其中参数为键码:
jButton1.setMnemonic(KeyEvent.VK_A);
这是在图形界面中处理热键的标准方式。只需按住 Alt 键 (windows),然后按您设置助记符的键即可。
Key Events 只发送给有焦点的组件。您没有 post 整个代码,但我猜焦点在您添加到框架的按钮上,因此该按钮获得 KeyEvent。
不确定您要使用 KeyListener 做什么。您无法通过查看在 KeyEvent 中键入的字符来判断单击了哪个按钮。
如果您想知道点击了哪个按钮,则需要为每个按钮添加一个 ActionListener
。阅读有关 How to Use Buttons 的 Swing 教程部分,了解更多信息和示例。