Это личное дело, но у вас, как правило, будет меньше проблем, если вы будете использовать что-то вроде KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, false)
сверх KeyStroke.getKeyStroke("W")
Эквивалентом KeyStroke.getKeyStroke("released W")
будет KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, true)
Я вернулсяи далее через ваш пример я попытался заменить KeyStroke.getKeyStroke("W")
на KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, false)
и его эквиваленты;Я попытался заменить флаги boolean
на Set
, и у меня все еще остается та же проблема
. Затем я пошел и выбросил ваш код и начал новый проект.Сначала я попробовал собственный маршрут рисования, и это сработало нормально.Затем я попробовал маршрут на основе компонентов, и это сработало ... 101
Итак, хотя у меня до сих пор нет «ответа» на вопрос, почему он не работает, у меня есть пример, который делает ...
Пример
И поскольку я действительно проверил свои предложения ...
import com.sun.glass.events.KeyEvent;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashSet;
import java.util.Set;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JLabel;
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) {
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 TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public enum Input {
UP, DOWN, LEFT, RIGHT
}
public class TestPane extends JPanel {
private Set<Input> inputs = new HashSet<>();
private int delta = 4;
private JLabel label;
public TestPane() {
InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = getActionMap();
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, false), "Up.pressed");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, true), "Up.relesed");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0, false), "Down.pressed");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0, true), "Down.relesed");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0, false), "Left.pressed");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0, true), "Left.relesed");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0, false), "Right.pressed");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0, true), "Right.relesed");
actionMap.put("Up.pressed", new InputAction(Input.UP, true));
actionMap.put("Up.relesed", new InputAction(Input.UP, false));
actionMap.put("Down.pressed", new InputAction(Input.DOWN, true));
actionMap.put("Down.relesed", new InputAction(Input.DOWN, false));
actionMap.put("Left.pressed", new InputAction(Input.LEFT, true));
actionMap.put("Left.relesed", new InputAction(Input.LEFT, false));
actionMap.put("Right.pressed", new InputAction(Input.RIGHT, true));
actionMap.put("Right.relesed", new InputAction(Input.RIGHT, false));
setLayout(null);
label = new JLabel();
label.setBackground(Color.RED);
label.setOpaque(true);
label.setBounds(0, 0, 10, 10);
add(label);
Timer timer = new Timer(5, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int xPos = label.getX();
int yPos = label.getY();
if (inputs.contains(Input.UP)) {
yPos -= delta;
}
if (inputs.contains(Input.DOWN)) {
yPos += delta;
}
if (inputs.contains(Input.LEFT)) {
xPos -= delta;
}
if (inputs.contains(Input.RIGHT)) {
xPos += delta;
}
if (xPos < 0) {
xPos = 0;
} else if (xPos + 10 > getWidth()) {
xPos = getWidth() - 10;
}
if (yPos < 0) {
yPos = 0;
} else if (yPos + 10 > getHeight()) {
yPos = getHeight() - 10;
}
label.setLocation(xPos, yPos);
repaint();
}
});
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
// protected void paintComponent(Graphics g) {
// super.paintComponent(g);
// Graphics2D g2d = (Graphics2D) g.create();
// g2d.setColor(Color.RED);
// g2d.drawRect(xPos, yPos, 10, 10);
// g2d.dispose();
// }
public class InputAction extends AbstractAction {
private Input input;
private boolean pressed;
public InputAction(Input input, boolean pressed) {
this.input = input;
this.pressed = pressed;
}
@Override
public void actionPerformed(ActionEvent e) {
if (pressed) {
inputs.add(input);
} else {
inputs.remove(input);
}
}
}
}
}
Примечание ...
Этот "тип" вопросаВ последнее время меня часто спрашивают, я предполагаю, что это какое-то классовое задание, так как мы видели несколько вариантов этого стиля кода.Как мы неоднократно советовали, использование компонентов таким способом не рекомендуется, поскольку они не предназначены для такого рода вещей.Вы получите лучшие (и более легкие) результаты, используя собственный маршрут рисования, как показано в Перемещение JLabel с помощью ключевых ставок