Java repaint() 方法在我尝试从面板中删除形状时不起作用



我想每秒画一些圆圈,然后从面板中将它们全部(或至少一个(删除。

这是现有的代码:

public class DrawShape {
ShapePanel panel;
public DrawShape(ShapePanel panel) {
this.panel = panel;
Timer t = new Timer();
t.schedule(new TimerTask() {
long startTime = System.currentTimeMillis();
int secondsToRun = 3;
@Override
public void run() {
if (System.currentTimeMillis() - startTime > secondsToRun * 1000) {
panel.deleteCircle();
System.out.println("t" + panel.circles.size());
cancel();
} else {
panel.addCircle(new Circle((int) (Math.random() * 200), (int) (Math.random() * 200)));
System.out.println(panel.circles.size());
}
}
}, 0, 1000);
}
}

如果时间大于 3 秒,请删除所有圆圈,否则继续在屏幕上绘制圆圈。

下面是ShapePanel类:

public class ShapePanel extends JPanel {
public List<Circle> circles = new LinkedList<Circle>();
public ShapePanel() {
// Setting up the frame
JFrame frame = new JFrame();
frame.setSize(500, 500);
frame.setVisible(true);
frame.setBackground(Color.black);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(this); // adding the panel to the frame
}
public void addCircle(Circle circle) {
circles.add(circle);
this.repaint();
}
public void deleteCircle() {
//        circles.remove(circles.get(0));
circles.clear(); //remove them all
this.repaint();
}
@Override
public void paint(Graphics g) {
for (Circle c : circles) {
g.setColor(Color.GREEN);
g.drawOval(c.x, c.y, Circle.radius * 2, Circle.radius * 2);
}
}
}

当我调用 deleteCircle(( 时,圆圈应该从列表中删除并重新绘制。我应该最终得到一个没有圆圈的空白屏幕。我认为在这种情况下重新粉刷不起作用。

PS:第一次问问题,如果很长,很抱歉:D

所以,有两件事立即出现在我面前。

  1. 使用java.util.Timer

Swing 不是线程安全的,由于java.util.Timer在它自己的线程中运行,因此更新 UI(或者在这种情况下,UI 所依赖的东西(可能会导致随机问题。

我会考虑改用javax.swing.Timer,因为它是在事件调度队列中触发的(并且通常使用起来更简单(

  1. 不调用super.paint

你没有考虑到paint做什么,也没有接管它的责任,在这种情况下,这将是为绘画"准备"Graphics环境。

Graphics是一个共享资源,它被传递给在油漆传递中更新的所有组件。 这意味着它将包含以前涂在它上面的东西。

两个建议:

  1. 作为一般建议,更喜欢覆盖paintComponent而不是paint(paint做很多重要的工作,所以除非你愿意做,否则通常是在油漆链中排名靠前(
  2. 在进行任何自定义绘画之前,请先致电super.paintComponent

我强烈推荐阅读:

  • 执行自定义绘画
  • 在AWT和Swing中绘画

  • 摇摆中的并发
  • 如何使用摆动计时器

最新更新