我正在尝试制作一个矩形在屏幕上移动,但它只是重新绘制而不是摆脱前面的矩形,使它看起来像一个巨大的矩形在屏幕上。任何帮助将不胜感激,这是我的代码:
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.Timer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.*;
@SuppressWarnings("serial")
public class Test extends JFrame implements ActionListener{
int x=50;
Timer tm = new Timer(30,this);
public static void main(String[] args){
new Test();
}
public Test(){
this.setSize(700, 500);
this.setTitle("Drawing Shapes");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
public void paint(Graphics g){
Graphics2D graph2 = (Graphics2D)g;
Shape Rect = new Rectangle2D.Float(x, 50, 50, 30);
graph2.setColor(Color.RED);
graph2.fill(Rect);
tm.start();
}
public void actionPerformed(ActionEvent e){
x=10+x;
repaint();
}
}
答案 0 :(得分:4)
paintComponent(Graphics g)
覆盖绘制方法应该在其第一行调用super.paintComponent(g);
。这将删除旧图像。答案 1 :(得分:2)
你打破了油漆链...
public void paint(Graphics g){
// Broken here...
Graphics2D graph2 = (Graphics2D)g;
Shape Rect = new Rectangle2D.Float(x, 50, 50, 30);
graph2.setColor(Color.RED);
graph2.fill(Rect);
tm.start();
}
你必须致电super.paint
。有关在Swing中绘画的更多详细信息,请参阅Painting in AWT and Swing和Performing Custom Painting
顶级容器不是双缓冲的,不建议直接对它们进行绘制,而是创建一个自定义组件,该组件从JPanel
扩展并覆盖它的paintComponent
方法(调用{{ 1}}在执行任何自定义绘画之前)
作为一般经验法则,您应该避免从super.paintComponent
这样的顶级容器扩展,因为您没有向类中添加任何新功能,并且它们将您锁定在一个用例中,从而减少了 - 课程的可用性
不要在JFrame
方法中调用tm.start
,除了paint之外你不应该在paint方法中做任何事情,不要尝试修改状态或以其他方式执行可能间接修改状态的动作一个组件,这是让程序消耗CPU的好方法
答案 2 :(得分:1)
添加其他已经说明的内容,
我注意到您使用this.setLocationRelativeTo(null)
作为简单的应用程序。不是说它不好,但你可能想检查这个线程以确保它是你想要的。