【发布时间】:2021-04-18 22:43:19
【问题描述】:
所以我有一个绘制的矩形,我想用箭头键移动它,包括对角线移动,或者更确切地说,允许同时按下多个键(换句话说,移动类似于 2D 中的玩家移动游戏)。我试图用一个不起作用的 KeyListener 来做到这一点。所以我决定转向 KeyBindings,我从这个网站上找到了一个例子:https://coderanch.com/t/606742/java/key-bindings(Rob Camick 的帖子)
我直接复制了代码,它按预期工作,除了它正在移动一个图标而不是像我想要的那样绘制一个矩形。我试图修改代码,以便它可以移动一个绘制的矩形,但只是失败了。这是我最近的尝试,也是最小的可重复性:
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class Test extends JPanel implements ActionListener
{
public JPanel component = this;
public int x = 100;
public int y = 100;
private Timer timer;
private int keysPressed;
private InputMap inputMap;
public void addAction(String name, int keyDeltaX, int keyDeltaY, int keyCode)
{
new NavigationAction(name, keyDeltaX, keyDeltaY, keyCode);
}
// Move the component to its new location
private void handleKeyEvent(boolean pressed, int deltaX, int deltaY)
{
keysPressed += pressed ? 1 : -1;
x += deltaX;
y += deltaY;
// Start the Timer when the first key is pressed
if (keysPressed == 1)
timer.start();
// Stop the Timer when all keys have been released
if (keysPressed == 0)
timer.stop();
}
// Invoked when the Timer fires
public void actionPerformed(ActionEvent e)
{
repaint();
}
class NavigationAction extends AbstractAction implements ActionListener
{
private int keyDeltaX;
private int keyDeltaY;
private KeyStroke pressedKeyStroke;
private boolean listeningForKeyPressed;
public NavigationAction(String name, int keyDeltaX, int keyDeltaY, int keyCode)
{
super(name);
this.keyDeltaX = keyDeltaX;
this.keyDeltaY = keyDeltaY;
pressedKeyStroke = KeyStroke.getKeyStroke(keyCode, 0, false);
KeyStroke releasedKeyStroke = KeyStroke.getKeyStroke(keyCode, 0, true);
inputMap.put(pressedKeyStroke, getValue(Action.NAME));
inputMap.put(releasedKeyStroke, getValue(Action.NAME));
component.getActionMap().put(getValue(Action.NAME), this);
listeningForKeyPressed = true;
}
public void actionPerformed(ActionEvent e)
{
// While the key is held down multiple keyPress events are generated,
// we only care about the first event generated
if (listeningForKeyPressed)
{
handleKeyEvent(true, keyDeltaX, keyDeltaY);
inputMap.remove(pressedKeyStroke);
listeningForKeyPressed = false;
}
else // listening for key released
{
handleKeyEvent(false, -keyDeltaX, -keyDeltaY);
inputMap.put(pressedKeyStroke, getValue(Action.NAME));
listeningForKeyPressed = true;
}
}
}
public void paintComponent(Graphics tool) {
super.paintComponent(tool);
System.out.println(x + ", " + y);
tool.drawRect(x, y, 50, 50);
}
public Test() {}
public static void main(String[] args)
{
new Test().create();
}
public void create() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setSize(600, 600);
frame.setLocationRelativeTo( null );
frame.getContentPane().add(component);
inputMap = component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
timer = new Timer(24, this);
timer.setInitialDelay( 0 );
addAction("Left", -3, 0, KeyEvent.VK_LEFT);
addAction("Right", 3, 0, KeyEvent.VK_RIGHT);
addAction("Up", 0, -3, KeyEvent.VK_UP);
addAction("Down", 0, 3, KeyEvent.VK_DOWN);
frame.setVisible(true);
}
}
【问题讨论】:
-
我从这个网站上找到了一个例子:coderanch.com/t/606742/java/key-bindings - 这不是我在你上一个问题中提供给你的链接:stackoverflow.com/questions/67066490/…
-
@camickr 是的,这不是您提供的链接,但是,我确实尝试使用您的链接并使用它。我觉得没有必要同时发布这两个链接,而且由于您的链接看起来像是您写的,我不希望在您允许发布它时遇到任何麻烦,而且我也对另一个链接做了更多的工作.对此感到抱歉。但我想我有我的解决方案,有人在下面发布。无论如何,感谢您提供该代码,它确实让我深入了解了所有这些键绑定内容。
-
我提供的链接将包含最新的建议,并且是我推荐的方法。你为什么要去寻找另一个链接?即使您从我这里找到了另一个链接,为什么还要在此处发布该代码,因为那不是我推荐的代码? 我在另一个链接上也做了更多的工作 - 那么与我推荐的链接相比,为什么你会花更多的时间在另一个链接上?提供我提供的链接是有原因的。
-
@camickr 所以我真的无法理解你推荐的那个,我感谢你推荐那个。我去寻找其他代码的原因是因为我有点放弃尝试修改您的代码。那时我发现了你的其他旧代码,而且,从我的立场来看,更清楚。所以,因为我更好地理解了其他代码,所以我能够更好地修改它。而且,由于我对其进行了更多修改,因此发布旧代码而不是您建议的代码似乎更合适。我希望我没有以任何方式冒犯您,我只是想让阅读此问题的每个人都清楚。
标签: java swing key-bindings