我正在尝试用Windowbuilder创建一个小程序,它只需在JPanel中绘制一个红色矩形(称为car1),并通过按箭头键来移动它;为了做到这一点,我将一个改变x位置的方法与箭头相关联,并调用Repait方法,但矩形根本不移动——因此,我可能会把KeyEvent和/或Repait搞砸。
每次按正确的箭头键移动并刷新面板时,我应该怎么做才能使矩形移动并刷新面板?
public class Car extends JPanel {
int x;
int y;
public Car(int x,int y){
this.x=x;
this.y=y;
}
public void paint(Graphics g) {
g.setColor(Color.RED);
g.fillRect(x, y, 20, 20);
}
public void move_right(){
x=x+20;
}
public void move_left(){
x=x-20;
}
}
public class Form extends JFrame {
//private JPanel contentPane;
Car car1;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Form frame = new Form();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Form() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 727, 550);
getContentPane().setLayout(null);
car1 = new Car(350, 480);
car1.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_KP_LEFT) {
car1.move_left();
car1.repaint();
}
if (key == KeyEvent.VK_KP_RIGHT) {
car1.move_right();
car1.repaint();
}
}
});
car1.setBounds(0, 0, 700, 500);
car1.setBackground(new Color(255, 255, 255));
getContentPane().add(car1);
}
}
这是一个解决方案:
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
car1.move_left();
car1.repaint();
}
if (key == KeyEvent.VK_RIGHT) {
car1.move_right();
car1.repaint();
}
}
});
错误在哪里:
addKeyListener
:将密钥侦听器添加到帧,而不是面板VK_KP_u
:改用VK_
前缀keyTyped
:使用按键
下一步你必须解决的是删除以前的矩形
至少有3个问题:
KeyListener
<众所周知,code>KeyListener只响应可聚焦且具有键盘焦点的组件上发生的按键事件。默认情况下,JPanel
不可聚焦,因此无法接收键盘聚焦。更好的解决方案是使用键绑定API,它允许定义组件在触发绑定之前必须具有的焦点级别,并允许您对多个键重复使用操作
,减少代码重复例如
import java.awt.Dimension;
import java.awt.EventQueue;
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 (Exception 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 class TestPane extends JPanel {
private int xPos;
public TestPane() {
Action leftAction = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
xPos -= 2;
if (xPos < 0) {
xPos = 0;
}
repaint();
}
};
Action rightAction = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
xPos += 2;
if (xPos + 10 > getWidth()) {
xPos = getWidth() - 10;
}
repaint();
}
};
bindKeyStroke(WHEN_IN_FOCUSED_WINDOW, "move.left", KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), leftAction);
bindKeyStroke(WHEN_IN_FOCUSED_WINDOW, "move.left", KeyStroke.getKeyStroke(KeyEvent.VK_KP_LEFT, 0), leftAction);
bindKeyStroke(WHEN_IN_FOCUSED_WINDOW, "move.left", KeyStroke.getKeyStroke(KeyEvent.VK_4, 0), leftAction);
bindKeyStroke(WHEN_IN_FOCUSED_WINDOW, "move.left", KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), leftAction);
bindKeyStroke(WHEN_IN_FOCUSED_WINDOW, "move.right", KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), rightAction);
bindKeyStroke(WHEN_IN_FOCUSED_WINDOW, "move.right", KeyStroke.getKeyStroke(KeyEvent.VK_KP_RIGHT, 0), rightAction);
bindKeyStroke(WHEN_IN_FOCUSED_WINDOW, "move.right", KeyStroke.getKeyStroke(KeyEvent.VK_6, 0), rightAction);
bindKeyStroke(WHEN_IN_FOCUSED_WINDOW, "move.right", KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), rightAction);
}
protected void bindKeyStroke(int condition, String name, KeyStroke keyStroke, Action action) {
InputMap im = getInputMap(condition);
ActionMap am = getActionMap();
im.put(keyStroke, name);
am.put(name, action);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int yPos = (getHeight() - 10) / 2;
g2d.drawRect(xPos, yPos, 10, 10);
g2d.dispose();
}
}
}
我现在正在实验JavaFX,教自己如何使用箭头键移动文本和项。我做了一个程序,如果按下箭头键,就可以简单地在舞台上移动文本。 我想使一个圆圈移动我的窗格,而不是文本。要使用箭头键移动我的圆圈,我必须做哪些更改?
问题内容: 我正在尝试创建一个简单游戏的开始。我要做的第一件事是将图形导入到我的代码中,然后在屏幕上移动它。我能够在屏幕上画一个球并四处移动,但是当我从文件导入图形时,无法四处移动。我想念什么或做错什么? 我的司机是在另一个班级,如下所示: 问题答案: 这里有两个大问题: 您正在从中读取文件。 永远 不要这样做,因为这会不必要地减慢绘图速度。可能在构造函数中读取一次图像,然后在图形中使用存储的im
问题内容: 我正在尝试通过keyEvent向左移动一个圆圈。到目前为止,圆已在窗口上绘制,但不会向左移动!我觉得问题是我在容器中添加了Window()构造函数。在控制台上没有输出告诉我它正在工作。因此,我认为它甚至不会到达KeyEvent类。这是我的代码: 问题答案: 实际上,这是您要添加到的内容,但重点是,因此,当您键入内容时,该内容将转到与类无关的内容。因此,为了克服它,你只需要调用的类的对象
问题内容: 我在JScrollPane中有一个JTextArea组件,并且文本区域不可编辑。我想使用向上和向下箭头键滚动文本区域(即,按箭头键将文本区域滚动一行)。任何想法如何实现这一目标? 问题答案: 是的,键绑定是必经之路,但是您不一定总是需要创建自己的动作。Swing组件带有您经常可以重用的默认操作。 有关这些操作的完整列表,请参见键绑定。 现在您知道了动作名称,您可以将其绑定到keyStr
我有一个名为“DisplayPanel”的类(它扩展了JPanel),我在那里画了一个正方形,它来自一个名为“square”的类(它扩展了JComponent)。如何使用键在JPanel中移动矩形? 正方形类有通常的绘制方法: “squarishThing”是一个普通矩形: 问题是:与“游戏库”不同,尝试“手动”做这样的事情是相当令人困惑的。我不知道“while循环”去哪里了。我试图在显示面板中放
问题内容: 所有四个箭头键(左上右下)的utf8代码是什么? 我正在学习node.js,并且试图检测何时按下了这些键。 这是我的工作,但是没有一个能捕获箭头键…我是node.js的新手,所以我在这里可能做得很愚蠢。 谢谢。 问题答案: 您可以使用按键包。尝试页面上给出的示例。 您可以按顺序获取箭头键的UTF-8值。