当我最终弄清楚重绘方法时,我遇到了一个问题。我想在屏幕上移动一个矩形,而不是再次重新绘制它。重绘很好,但它留下了旧的矩形!这是我的代码:
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);
}
}
如何让留下的矩形消失(我不想清除完整的窗口)?或者甚至更好的是,如何让矩形移动&#39; (如果可能的话)?
我的最终结果:
最终我想要的是什么:
注意:在这一点上简单地绘制矩形并不是我想要的。我希望看到它被拖过来。
答案 0 :(得分:9)
您的问题是您只绘制矩形而不是整个面板,因此当您调用方法时,面板最终会充满矩形。您还需要绘制面板的背景。这将“擦除”前面的矩形,因此面板只包含您在该特定调用中绘制的内容,而不是您之前执行的操作。要完成此任务,您需要致电:
super.paintComponent(g);
在paintComponent
方法的开头(在绘制任何其他内容之前)。这是有效的,因为paintComponent
在空JPanel中唯一需要做的就是绘制背景。
所以:
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g.drawRect(user.x, user.y, 10, 10);
}
修改强>
回答你的一些评论:
我想在屏幕上移动一个矩形,而不是再次重新绘制它。
没有“移动”矩形这样的东西。你可以把东西画在屏幕上。如果你想看到其他东西,你必须绘制其他东西。没有固有的“将像素的颜色移动到像素......”,这不是它的工作原理。你想要的东西吗?画出它们。你想要他们搬家吗?在不同的位置重复绘制它们。
(我不想清除完整的窗口)
但你做到了。每次必须更改时,您都希望重新绘制整个面板。如果面板中还有其他东西你不想“擦除”,那么重新绘制它们。
要清楚,可以只清除“旧”矩形位置并绘制一个新位置,而不会影响面板的其余部分。但这是不必要的棘手问题。覆盖paintComponent
时,第一行中调用super.paintComponent(g)
是标准过程。不要说它必须是一个非常有意识的决定,你最好确定你在做什么。
如果您的程序在重新绘制面板背景时导致部分代码行为异常,我可以放心地告诉您,这些部分设计不合理而不是调用{{1}是个坏主意。
super.paintComponent(g)
负责绘制整个组件。背景是组件的一部分。在Swing中自然而且很好的设计,当你覆盖它时就这样做。