我正在尝试使用Windowbuilder创建一个小程序,只需在JPanel中绘制一个红色矩形(称为car1),然后按箭头键移动它;要做到这一点我与箭头相关联一个方法来改变x位置调用重绘方法,但矩形根本不移动 - 因此我可能搞乱了KeyEvent和/或重绘的东西。
每次按下正确的箭头键移动并刷新面板,我该怎么做才能制作矩形?
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);
}
}
答案 0 :(得分:2)
至少有3个问题:
KeyListener
。众所周知,KeyListener
仅响应在可聚焦且具有键盘焦点的组件上发生的关键事件。默认情况下,JPanel
无法对焦,因此无法接收键盘焦点。更好的解决方案是使用键绑定API,它允许在触发绑定之前定义组件必须具有的焦点级别,并允许您为多个键重用Action
,从而减少代码重复paint
。强烈建议在执行自定义绘画时覆盖paintComponent
而不是绘画。你也未能保持油漆链,这将导致奇怪和美妙的油漆工艺的结束。 Painting in AWT and Swing和Performing Custom Painting了解详情null
布局。避免使用null
布局,像素完美布局是现代ui设计中的错觉。影响组件个体大小的因素太多,您无法控制。 Swing旨在与布局管理器一起工作,放弃这些将导致问题和问题的结束,您将花费越来越多的时间来纠正例如......
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();
}
}
}
答案 1 :(得分:0)
这是一个解决方案:
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_
:使用VK_
前缀代替keyTyped
:使用keyPressed
代替下一步你必须解决的是删除以前的矩形