我正在用Java创建一个程序,你可以移动一个正方形。但是,广场不动。我尝试了很多东西,但没有一个能奏效。这似乎是一个重绘的问题。我怎么能解决这个问题?
package movingSquare;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
public class MovingSquare extends JComponent {
private static final long serialVersionUID = -3778627464016140311L;
public static JFrame f = new JFrame("Moving Square");
public static int x;
public static int y;
public static Rectangle r = new Rectangle(x, y, 20, 20);
public static MovingSquare mv = new MovingSquare();
public static KeyListener kl = new KeyListener() {
@Override
public void keyPressed(KeyEvent arg0) {
// TODO Auto-generated method stub
if(arg0.getKeyCode() == KeyEvent.VK_UP) {
y += 1;
r.setLocation(x, y);
mv.repaint(r);
}
if(arg0.getKeyCode() == KeyEvent.VK_DOWN) {
y -= 1;
r.setLocation(x, y);
mv.repaint();
}
if(arg0.getKeyCode() == KeyEvent.VK_LEFT) {
x -= 1;
r.setLocation(x, y);
mv.repaint();
}
if(arg0.getKeyCode() == KeyEvent.VK_RIGHT) {
x += 1;
r.setLocation(x, y);
mv.repaint();
}
}
@Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}};
public static void main(String[] args) {
// TODO Auto-generated method stub
f.setBackground(Color.BLUE);
f.setMinimumSize(new Dimension(720, 720));
f.setResizable(false);
f.setFocusable(true);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.addKeyListener(kl);
f.add(new MovingSquare());
f.pack();
f.setVisible(true);
boolean e = true;
while(e) {
System.out.println("x: " + x + " y: " + y);
}
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g1 = (Graphics2D) g;
g1.setColor(Color.BLUE);
g1.fillRect(0, 0, 720, 720);
g1.setColor(Color.RED);
g1.fill(r);
}
}
答案 0 :(得分:-1)
首先,自定义绘制是通过覆盖paintComponent()
而不是绘制()来完成的。
摆脱所有静态变量。创建自定义类的原因是您可以定义包含类属性的变量。
不需要将帧变量作为类的一部分。组件只需要知道自己,而不是它所属的框架。
f.add(new MovingSquare());
首先创建一个MovingSquare组件并将其添加到框架中。
public static MovingSquare mv = new MovingSquare();
但是你创建了另一个MovingSquare组件,但是从不添加它做框架,所以你永远无法绘制它。
除去上述声明,因为您的课程已经是MovingSquare,所以不需要它。
mv.repaint();
正如我上面所说,该声明什么都不做,因为该组件永远不会添加到帧中。
相反,代码应为:
repaint();
这就是使组件重新绘制所需的全部内容。
如果使用KeyListener,则应将KeyListener添加到组件本身,而不是帧。组件应负责管理自己的状态。
所以基本上你的设计是错误的,需要修复。
但是,即使这样也可能无法解决问题,因为只有具有焦点的组件才会收到事件,并且正如评论中建议的那样,您应该使用Key Bindings
。
请查看Motion Using the Keyboard的工作示例,以证明KeyEvents和Key Bindings之间的区别。