Java JFrame的无响应KeyListener
我正在尝试为我的Java JFrame的无响应KeyListener,java,swing,jframe,keylistener,Java,Swing,Jframe,Keylistener,我正在尝试为我的JFrame实现一个KeyListener。在构造函数上,我使用以下代码: System.out.println("test"); addKeyListener(new KeyListener() { public void keyPressed(KeyEvent e) { System.out.println( "tester"); } public void keyReleased(KeyEvent e) { System.out.println("2tes
JFrame
实现一个KeyListener
。在构造函数上,我使用以下代码:
System.out.println("test");
addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent e) { System.out.println( "tester"); }
public void keyReleased(KeyEvent e) { System.out.println("2test2"); }
public void keyTyped(KeyEvent e) { System.out.println("3test3"); }
});
当我运行它时,控制台中会出现test
消息。但是,当我按下一个键时,我没有收到任何其他消息,就好像keylister
根本不在那里
我想这可能是因为重点不在JFrame
因此,它们不会接收任何事件。但是,我敢肯定是的
有什么我遗漏的吗?嗯。。你的构造函数是什么类的?可能是某个类扩展了JFrame?当然,窗口焦点应该在窗口,但我认为这不是问题所在 我扩展了你的代码,试着运行它,它成功了——按键作为打印输出。(通过Eclipse使用Ubuntu运行):
必须将keyListener添加到所需的每个组件中。只有具有焦点的组件才会发送这些事件。例如,如果JFrame中只有一个文本框,则该文本框具有焦点。因此,您还必须向该组件添加一个KeyListener 过程是一样的:
myComponent.addKeyListener(new KeyListener ...);
注意:有些组件像JLabel一样不可聚焦
要将其设置为可聚焦,您需要:
myComponent.setFocusable(true);
KeyListener
为低级别,仅适用于单个组件。尽管试图使其更可用,JFrame还是创建了许多组件,最明显的是内容窗格JComboBox
UI通常也以类似的方式实现
值得注意的是,鼠标事件的工作方式与按键事件略有不同
有关您应该做什么的详细信息,请参阅我的答案。我遇到了相同的问题,直到我了解到真正的问题是关于聚焦。您的JFrame已经添加了侦听器,但tour frame从未聚焦,因为您的JFrame中有许多组件也是可聚焦的,所以请尝试:
JFrame.setFocusable(true);
祝你好运如果你不想在每个组件上注册侦听器,
您可以将自己的
KeyEventDispatcher
添加到KeyboardFocusManager
:
public class MyFrame extends JFrame {
private class MyDispatcher implements KeyEventDispatcher {
@Override
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_PRESSED) {
System.out.println("tester");
} else if (e.getID() == KeyEvent.KEY_RELEASED) {
System.out.println("2test2");
} else if (e.getID() == KeyEvent.KEY_TYPED) {
System.out.println("3test3");
}
return false;
}
}
public MyFrame() {
add(new JTextField());
System.out.println("test");
KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
manager.addKeyEventDispatcher(new MyDispatcher());
}
public static void main(String[] args) {
MyFrame f = new MyFrame();
f.pack();
f.setVisible(true);
}
}
我也有同样的问题。我听从了Bruno的建议,发现在JFrame中的“第一个”按钮(即左上角)上添加一个KeyListener就成功了。但我同意你的看法,这是一种令人不安的解决办法。所以我四处闲逛,找到了一个更整洁的方法来修复它。只要加一行就行了
myChildOfJFrame.requestFocusInWindow();
在您创建JFrame子类的实例并将其设置为可见之后,可以使用main方法 Deion(以及其他任何提出类似问题的人),您可以使用上面的Peter代码,但不是打印到标准输出,而是测试按下、释放或键入的键代码
@Override
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_PRESSED) {
if (e.getKeyCode() == KeyEvent.VK_F4) {
dispose();
}
} else if (e.getID() == KeyEvent.KEY_RELEASED) {
if (e.getKeyCode() == KeyEvent.VK_F4) {
dispose();
}
} else if (e.getID() == KeyEvent.KEY_TYPED) {
if (e.getKeyCode() == KeyEvent.VK_F4) {
dispose();
}
}
return false;
}
为了捕获JFrame中所有文本字段的关键事件, 可以使用关键事件后处理器。 下面是一个工作示例,在添加明显的includes之后
public class KeyListenerF1Demo extends JFrame implements KeyEventPostProcessor {
public static final long serialVersionUID = 1L;
public KeyListenerF1Demo() {
setTitle(getClass().getName());
// Define two labels and two text fields all in a row.
setLayout(new FlowLayout());
JLabel label1 = new JLabel("Text1");
label1.setName("Label1");
add(label1);
JTextField text1 = new JTextField(10);
text1.setName("Text1");
add(text1);
JLabel label2 = new JLabel("Text2");
label2.setName("Label2");
add(label2);
JTextField text2 = new JTextField(10);
text2.setName("Text2");
add(text2);
// Register a key event post processor.
KeyboardFocusManager.getCurrentKeyboardFocusManager()
.addKeyEventPostProcessor(this);
}
public static void main(String[] args) {
JFrame f = new KeyListenerF1Demo();
f.setName("MyFrame");
f.pack();
f.setVisible(true);
}
@Override
public boolean postProcessKeyEvent(KeyEvent ke) {
// Check for function key F1 pressed.
if (ke.getID() == KeyEvent.KEY_PRESSED
&& ke.getKeyCode() == KeyEvent.VK_F1) {
// Get top level ancestor of focused element.
Component c = ke.getComponent();
while (null != c.getParent())
c = c.getParent();
// Output some help.
System.out.println("Help for " + c.getName() + "."
+ ke.getComponent().getName());
// Tell keyboard focus manager that event has been fully handled.
return true;
}
// Let keyboard focus manager handle the event further.
return false;
}
}
哈哈。。。。你所要做的就是确保 addKeyListener(此)
已正确放置在代码中。您可以让自定义JComponents将其父JFrame设置为可聚焦 只需添加一个构造函数并在JFrame中传递。然后在paintComponent中调用setFocusable()
这样,无论是否按下其他组件,JFrame都将始终接收关键事件。InputMaps和ActionMaps旨在捕获组件、组件及其所有子组件或整个窗口的关键事件。这是通过JComponent.getInputMap()中的参数控制的。有关文档,请参阅 这种设计的美妙之处在于,人们可以选择哪些关键的笔划是需要监控的,并根据这些关键的笔划触发不同的动作 当escape键在窗口中的任何位置被按下时,此代码将在JFrame上调用dispose()。JFrame不是从JComponent派生的,因此必须使用JFrame中的另一个组件来创建键绑定。内容窗格可能就是这样一个组件
InputMap inputMap;
ActionMap actionMap;
AbstractAction action;
JComponent component;
inputMap = component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
actionMap = component.getActionMap();
action = new AbstractAction()
{
@Override
public void actionPerformed(ActionEvent e)
{
dispose();
}
};
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "dispose");
actionMap.put("dispose", action);
这应该会有所帮助
yourJFrame.setFocusable(true);
yourJFrame.addKeyListener(new java.awt.event.KeyAdapter() {
@Override
public void keyTyped(KeyEvent e) {
System.out.println("you typed a key");
}
@Override
public void keyPressed(KeyEvent e) {
System.out.println("you pressed a key");
}
@Override
public void keyReleased(KeyEvent e) {
System.out.println("you released a key");
}
});
我也得到了所有的消息输出。在Windows命令行中运行。您将获得所有消息,因为在本例中,JFrame具有焦点。尝试在JFrame中添加一个文本框组件,看看会发生什么。是的,当程序启动时,您可以稍微看到焦点在按钮a上。为每个按钮添加一个keylistener修复了这个问题。这有点奇怪,我认为在JFrame中添加一个keylistener会起作用,但我想不会。谢谢我在JFrame上制作了一个侦听器,它可以从键盘进行侦听。我想让它在被动模式下工作,即使窗口不在前面(聚焦)。JFrice没有在被动模式下收听。对于一个工作示例,您可以考虑添加导入。我通常添加“包导入”以保持简短。否则,+1。有趣的技巧。你真的应该解释一下“正确的位置”,让这成为一个有用的答案。-1绝对不是-这在不止一个方面是完整的:a)不雅的子类化b)不雅的引用传递c)绘画时不适当的状态更改d)…KeyboardFocusManager应用广泛,如果你有多个帧,你会遇到麻烦吗?所以这应该是可行的,比如:foreach(“帧中的可聚焦组件”如{uuuu.addkeylistener(frameKeylistener);}我发现这只在我使用JFrame上的东西之前有效,然后KeyListener不再响应Hanks,出现了同样的问题。奇怪的是,即使是内容窗格,组件也会失去焦点。。。
yourJFrame.setFocusable(true);
yourJFrame.addKeyListener(new java.awt.event.KeyAdapter() {
@Override
public void keyTyped(KeyEvent e) {
System.out.println("you typed a key");
}
@Override
public void keyPressed(KeyEvent e) {
System.out.println("you pressed a key");
}
@Override
public void keyReleased(KeyEvent e) {
System.out.println("you released a key");
}
});