java - 使用 KeyListener 移动矩形
问题描述
我正在尝试使用 KeyListener 移动一个矩形。我见过其他人使用相同的代码,但由于某种原因我无法让它移动。现在矩形确实出现了。我不确定如果我遗漏了什么,我是否忘记了什么。这是我的代码:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.Graphics;
public class roomwars extends JPanel implements ActionListener, KeyListener {
//public JPanel pane;
public JFrame frame;
public JButton start, help;
public JTextField box;
int x=0, y=0, velx =0, vely =0;
Timer t = new Timer(5, this);
public void run(){
frame = new JFrame("ROOM WARS!");
frame.setSize(700, 700);
frame.setVisible(true);
frame.add(this);
}
public void second (){
t.start();
addKeyListener(this);
//setFocusalbe(true);
//SETFocusTraversalKeyEnabled(false);
}
public void paintComponent(Graphics g) {
Color mypurple = new Color(34, 0, 56);
g.setColor(mypurple);
g.fillRect(x, y, 30, 30);
//g.setColor(Color.PINK);
//g.fillRect(655,632,30,30);
}
public void actionPerformed(ActionEvent e){
repaint();
x+= velx;
y+= vely;
}
public void keyPressed(KeyEvent e){
int code = e.getKeyCode();
if (code == KeyEvent.VK_UP){
vely = -1;
velx = 0;
}
else if (code == KeyEvent.VK_DOWN) {
vely = 1;
velx = 0;
}
else if (code == KeyEvent.VK_RIGHT) {
velx = -1;
vely = 0;
}
else if (code == KeyEvent.VK_LEFT) {
velx = 1;
vely = 0;
}
}
public void keyTyped(KeyEvent e){}
public void keyReleased(KeyEvent e) {}
public static void main(String[] args) {
new roomwars().run();
}
}
解决方案
除了不尊重油漆链(和调用super.paintComponent
)之外,你的主要问题是使用KeyListener
.
少量的搜索会很快告诉您,KeyListener
因为不响应而臭名昭著,因为这通常是不可靠的。
最常见的解决方案是使用键绑定 API
以下是在当前代码库中实现键绑定的非常简单的示例
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.IOException;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) throws IOException, InterruptedException {
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.add(new RoomWars());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class RoomWars extends JPanel implements ActionListener {
//public JPanel pane;
int x = 0, y = 0, velx = 0, vely = 0;
Timer t = new Timer(5, this);
public RoomWars() {
t.start();
InputMap im = getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "up.pressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "up.released");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "down.pressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "down.released");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "left.pressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "left.released");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "right.pressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "right.released");
am.put("up.pressed", new MoveAction(-1, 0));
am.put("up.released", new MoveAction(0, 0));
am.put("down.pressed", new MoveAction(1, 0));
am.put("down.released", new MoveAction(0, 0));
am.put("left.pressed", new MoveAction(0, -1));
am.put("left.released", new MoveAction(0, 0));
am.put("right.pressed", new MoveAction(0, 1));
am.put("right.released", new MoveAction(0, 0));
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Color mypurple = new Color(34, 0, 56);
g.setColor(mypurple);
g.fillRect(x, y, 30, 30);
//g.setColor(Color.PINK);
//g.fillRect(655,632,30,30);
}
public class MoveAction extends AbstractAction {
private int yDelta;
private int xDelta;
public MoveAction(int yDelta, int xDelta) {
this.yDelta = yDelta;
this.xDelta = xDelta;
}
@Override
public void actionPerformed(ActionEvent e) {
vely = yDelta;
velx = xDelta;
}
}
public void actionPerformed(ActionEvent e) {
repaint();
x += velx;
y += vely;
}
}
}
推荐阅读
- c++ - 异构集合
- google-cloud-platform - 对 Google Cloud Console 进行身份验证后,“CheckCookie”302 重定向的标头中的 gidl 查询字符串参数代表什么?
- java - 如何使用 Java 将 Perl 哈希转换为 JSON?
- android-tv - 如何从 Android 源获取 WebOs 应用
- c++ - “bool *”类型的值不能分配给“bool (*)(intenemy_piece)”类型的实体
- c++ - 超出数组的大小如何工作但数组不够大?TCP/IP 客户端
- python - 访问pyspark.sql Row对象的时间复杂度
- python - 归并排序与归并-插入混合排序的比较次数关系
- grafana - 使用 Grafana 和 Loki 删除重复条目
- python - 如何将我 CRUD 的数据保存到 json 文件(python)