使用KeyAdapter的简单程序无法在按下多个按键后注册单个按键。代码解决方案?

【字号: 日期:2024-02-22浏览:62作者:雯心
如何解决使用KeyAdapter的简单程序无法在按下多个按键后注册单个按键。代码解决方案??

正如在类似问题中所讨论的,不要使用KeyListener,而要使用键绑定。摆动计时器可用于重复移动精灵。

例如:

import java.awt.Color;import java.awt.Dimension;import java.awt.Graphics;import java.awt.event.*;import java.util.EnumMap;import javax.swing.*;@SuppressWarnings('serial')public class Boxxy2 extends JPanel { private static final int PREF_W = 400; private static final int PREF_H = PREF_W; private static final int SQUARE_W = 20; private static final String pressed = 'pressed'; private static final String RELEASED = 'released'; public static final int MOVE_SCALE = 1; private static final int TIMER_DELAY = 5; private int squareX = 0; private int squareY = 0; private int squareW = SQUARE_W; private int squareH = SQUARE_W; private EnumMap<Direction, Boolean> dirMap = new EnumMap<>(Direction.class); public Boxxy2() { setupKeyBinding(); new Timer(TIMER_DELAY, new TimerListener()).start(); } private void setupKeyBinding() { int condition = JComponent.WHEN_IN_FOCUSED_WINDOW; InputMap inMap = getInputMap(condition); ActionMap actMap = getActionMap(); // this uses an enum of Direction that holds ints for the arrow keys for (Direction direction : Direction.values()) { dirMap.put(direction, Boolean.FALSE); int key = direction.getKey(); String name = direction.name(); Keystroke keypressed = Keystroke.getKeystroke(key, 0, false); Keystroke keyreleased = Keystroke.getKeystroke(key, 0, true); // add the key bindings for arrow key and shift-arrow key inMap.put(keypressed, name + pressed); inMap.put(keyreleased, name + RELEASED); actMap.put(name + pressed, new MyKeyAction(this, direction, true)); actMap.put(name + RELEASED, new MyKeyAction(this, direction, false)); } } @Override public Dimension getPreferredSize() { return new Dimension(PREF_W, PREF_H); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.RED); g.fillRect(squareX, squareY, squareW, squareH); } private static void createAndShowGui() { Boxxy2 mainPanel = new Boxxy2(); JFrame frame = new JFrame('Boxxy2'); frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(mainPanel); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokelater(new Runnable() { public void run() { createAndShowGui(); } }); } private class TimerListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { for (Direction dir : dirMap.keySet()) { if (dirMap.get(dir)) { squareX += MOVE_SCALE * dir.getRight(); squareY += MOVE_SCALE * dir.getDown(); } } repaint(); } } public void setMovement(Direction direction, boolean keypressed) { dirMap.put(direction, keypressed); }}enum Direction { UP(KeyEvent.VK_UP, 0, -1), DOWN(KeyEvent.VK_DOWN, 0, 1), LEFT(KeyEvent.VK_LEFT, -1, 0), RIGHT(KeyEvent.VK_RIGHT, 1, 0); private int key; private int right; private int down; private Direction(int key, int right, int down) { this.key = key; this.right = right; this.down = down; } public int getKey() { return key; } public int getRight() { return right; } public int getDown() { return down; }}// Actions for the key binding@SuppressWarnings('serial')class MyKeyAction extends AbstractAction { private Boxxy2 Boxxy2; private Direction direction; private boolean keypressed; public MyKeyAction(Boxxy2 Boxxy2, Direction direction, boolean keypressed) { this.Boxxy2 = Boxxy2; this.direction = direction; this.keypressed = keypressed; } @Override public void actionPerformed(ActionEvent e) { Boxxy2.setMovement(direction, keypressed); }}解决方法

我只是在尝试简单绘图程序的基础知识。我有一个程序可以绘制一个矩形,然后让我向任意方向移动它。我使用线程进行平滑操作。但是,令我困扰的是,如果我按下三个键并释放其中两个,程序将不会检测到第三个,从而使矩形保持静止。

我在这里要求太多,还是与硬件有关?我有一个很便宜的键盘。

如果您想兜风,这里是完整的程序。

import java.awt.Color;import java.awt.Graphics;import java.awt.Image;import java.awt.event.KeyAdapter;import java.awt.event.KeyEvent;import javax.swing.ImageIcon;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.SwingUtilities;public class Boxxy extends JFrame implements Runnable{ int xPos,yPos,xDir,yDir; MyPanel panel; ImageIcon ii; Image i; public Boxxy() {setSize(400,400);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setLocationRelativeTo(null);panel = new MyPanel();add(panel);setVisible(true); } class MyPanel extends JPanel {private static final long serialVersionUID = 1L;private int squareX = 0;private int squareY = 0;private int squareW = 20;private int squareH = 20;private MyPanel() { setFocusable(true); addKeyListener(new KeyAdapter() {public void keyPressed(KeyEvent e) { switch (e.getKeyCode()) { case (KeyEvent.VK_UP): setyDir(-1); break; case (KeyEvent.VK_DOWN): setyDir(1); break; case (KeyEvent.VK_LEFT): setxDir(-1); break; case (KeyEvent.VK_RIGHT): setxDir(1); break; }}public void keyReleased(KeyEvent e) { switch (e.getKeyCode()) { case (KeyEvent.VK_UP): setyDir(0); break; case (KeyEvent.VK_DOWN): setyDir(0); break; case (KeyEvent.VK_LEFT): setxDir(0); break; case (KeyEvent.VK_RIGHT): setxDir(0); break; }} });}private void repaintSquare(int x,int y) { int OFFSET = 1; if ((squareX!=x) || (squareY!=y)) {repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);squareX=x;squareY=y;repaint(squareX,squareH+OFFSET); }}protected void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.RED); g.fillRect(squareX,squareW,squareH);} } private void move() {panel.repaintSquare(xPos,yPos);xPos += xDir;yPos += yDir; } private void setxDir(int x) {this.xDir = x; } private void setyDir(int y) {this.yDir = y; } public static void main(String[] args) {Thread t = new Thread(new Boxxy());t.start(); } @Override public void run() {try { while(true) {move();Thread.sleep(5); }} catch (InterruptedException e) { e.printStackTrace();} }}

相关文章: