移动Java Swing矩形会留下矩形

4 java swing awt

当我最终弄清楚重绘方法时,我遇到了一个问题.我想在屏幕上移动一个矩形,而不是再次重新绘制它.重绘很好,但它留下了旧的矩形!这是我的代码:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Tutorial3{

    public static void main(String[] agrs){
        createAndStartGui();
    }
    static void createAndStartGui(){
        JFrame f = new JFrame("tutorial 3");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().setPreferredSize(new Dimension(500, 300));

        MyPanel panel = new MyPanel();
        f.add(panel);

        f.pack();
        f.setVisible(true);

        for (int i = 0; i < 10; i++){
            try {
                Thread.sleep(100);
            } catch (InterruptedException ex) {
                Logger.getLogger(Tutorial3.class.getName()).log(Level.SEVERE, null, ex);
            }
            panel.user.move("right");
            panel.repaint();
        }
    }
}

class MyRectangle{
    int x;
    int y;
    public MyRectangle(int x, int y){
        this.x = x;
        this.y = y;
    }
    void move(String direction){
        switch (direction){
            case "up":
                this.y -= 10;
                break;
            case "down":
                this.y += 10;
                break;
            case "left":
                this.x -= 10;
                break;
            case "right":
                this.x += 10;
                break;
            default:
                break;
        }
    }
}

class MyPanel extends JPanel{
    MyRectangle user = new MyRectangle(10, 10);
    public MyPanel(){

    }
    public void paintComponent(Graphics g){
        Graphics2D g2d = (Graphics2D) g;
        g.drawRect(user.x, user.y, 10, 10);
    }

}
Run Code Online (Sandbox Code Playgroud)

如何让留下的矩形消失(我不想清除完整的窗口)?或者更好的是,如何让矩形"移动"(如果可能的话)?

我的最终结果:

在此输入图像描述

我到底想要什么:

在此输入图像描述

注意:在这一点上简单地绘制矩形不是我想要的.我希望看到它被拖过来.

DSq*_*are 9

您的问题是您只绘制矩形而不是整个面板,因此当您调用方法时,面板最终会充满矩形.您还需要绘制面板的背景.这将"擦除"前面的矩形,因此面板只包含您在该特定调用中绘制的内容,而不是您之前执行的操作.要完成此任务,您需要致电:

super.paintComponent(g);
Run Code Online (Sandbox Code Playgroud)

paintComponent方法的开头(在绘制任何其他内容之前).这是有效的,因为paintComponent在空的JPanel中唯一需要做的就是绘制背景.

所以:

public void paintComponent(Graphics g){
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g;
    g.drawRect(user.x, user.y, 10, 10);
}
Run Code Online (Sandbox Code Playgroud)

编辑:

回答你的一些评论:

我想在屏幕上移动一个矩形,而不是再次重新绘制它.

没有"移动"矩形这样的东西.你可以把东西画在屏幕上.如果你想看到其他东西,你必须绘制其他东西.没有固有的"将像素的颜色移动到像素......",这不是它的工作原理.你想要的东西吗?画出它们.你想要他们搬家吗?在不同的位置重复绘制它们.

(我不想清除完整的窗口)

但你做了.每次必须更改时,您都希望重新绘制整个面板.如果面板中还有其他东西你不想"擦除",那么重新绘制它们.

为了清楚起见,可以只清除"旧"矩形位置并绘制一个新的矩形位置,而不会影响面板的其余部分.但这是不必要的棘手问题.当您在第一行覆盖paintComponent调用super.paintComponent(g)时是标准过程.不要把它作为一个非常有意识的决定,你最好确定你在做什么.

如果你的程序是以某种方式完成的,那么当你重新绘制面板的背景时,你的部分代码会出现问题,我可以放心地告诉你,这些部分设计super.paintComponent(g)得不好而且调用不是一个坏主意.

paintComponent有责任绘制整个组件.背景是组件的一部分.Swing中的自然和良好的设计,当你覆盖它时这样做.