问题描述
我在使用KeyListener
时遇到了困难(无法检测到键),我试图切换到KeyBindings,但JFrame
并没有扩展getInputMap()函数所需的JComponent
.有什么想法吗?
I've been have difficulty with KeyListener
(not detecting keys) and I'm trying to switch over to KeyBindings but JFrame
doesn't extend JComponent
which is needed for the getInputMap() function. Any ideas?
推荐答案
改为使用代理JComponent
.例如,将框架的contentPane
设置为JPanel
并使用它注册按键绑定.
Use a surrogate JComponent
instead. For example, set the frame's contentPane
to be a JPanel
and use it to register the key bindings.
这是一个非常基本的示例,它使用JPanel
作为contentPane
,并向其中添加Canvas
.然后,代表Canvas
通过JPanel
注册键绑定,而该键绑定实际上是用来对它们进行响应的.
This is a very basic example, which uses a JPanel
as the contentPane
and adds a Canvas
to it. The key bindings are then registered through the JPanel
on behalf of the Canvas
which is actually used to respond to them.
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Surface surface;
public TestPane() {
setLayout(new BorderLayout());
surface = new Surface();
InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = getActionMap();
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0, false), "Pressed.left");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0, true), "Release.left");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0, false), "Pressed.right");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0, true), "Release.right");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, false), "Pressed.up");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, true), "Release.up");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0, false), "Pressed.down");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0, true), "Release.down");
actionMap.put("Pressed.left", surface.getLeftPressAction());
actionMap.put("Release.left", surface.getLeftReleaseAction());
actionMap.put("Pressed.right", surface.getRightPressAction());
actionMap.put("Release.right", surface.getRightReleaseAction());
actionMap.put("Pressed.up", surface.getUpPressAction());
actionMap.put("Release.up", surface.getUpReleaseAction());
actionMap.put("Pressed.down", surface.getDownPressAction());
actionMap.put("Release.down", surface.getDownReleaseAction());
add(surface);
}
}
public class Surface extends Canvas {
private String displayText = "...";
@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g.create();
FontMetrics fm = g2d.getFontMetrics();
int x = (getWidth() - fm.stringWidth(displayText)) / 2;
int y = ((getHeight() - fm.getHeight()) / 2) + fm.getAscent();
g2d.drawString(displayText, x, y);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
public Action getLeftPressAction() {
return new TextAction("Left");
}
public Action getLeftReleaseAction() {
return new ClearAction();
}
public Action getRightPressAction() {
return new TextAction("Right");
}
public Action getRightReleaseAction() {
return new ClearAction();
}
public Action getUpPressAction() {
return new TextAction("Up");
}
public Action getUpReleaseAction() {
return new ClearAction();
}
public Action getDownPressAction() {
return new TextAction("Down");
}
public Action getDownReleaseAction() {
return new ClearAction();
}
public class TextAction extends AbstractAction {
private String text;
public TextAction(String text) {
this.text = text;
}
@Override
public void actionPerformed(ActionEvent e) {
displayText = text;
repaint();
}
}
public class ClearAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
displayText = "...";
repaint();
}
}
}
}
此示例仅覆盖Canvas
的paint
方法,但该概念仍应适用于使用BufferStrategy
This example only override's the Canvas
s paint
method, but the concept should still work for implementations using BufferStrategy
这篇关于是否可以在JFrame&中使用KeyBindings?帆布?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!