Java方块不动

时间:2017-01-05 17:41:30

标签: java swing awt repaint

我正在用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);
    }
}

1 个答案:

答案 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之间的区别。