Thread.sleep()停止了我的油漆?
我正在制作一个程序,试图让一张卡在屏幕上移动,就好像你真的从桌面上画了一样。 这是动画的代码:
public void move(int x, int y) { int curX = this.x; //the entire class extends rectangle int curY = this.y; // animate the movement to place for (int i = curX; i > x; i--) { this.x = i; } this.x = x; this.y = y; }
此矩形对象位于jframe内部的面板内。 重新粉刷小组,我有这个:
public void run() { while (Core.isRunning()) { gamePanel.repaint(); //panel in which my rectangle object is in try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } } }
这是一个线程,每50毫秒重新绘制一次gamePanel。
现在,我意识到这可能不是做这种事情的最好方法。 如果有更好的方法来做这整个重绘的事情,请通知我!
但是,我遇到的问题是,当我为我的矩形调用move()
命令时,它会通过线程,但图像不会更新直到结束,所以它只是从a点到最终位置的跳转。
为什么会这样? 谁能评论/改进我的代码? 谢谢!
问题是你在Event Dispatch Thread中调用Thread.sleep()
导致GUI无响应。 为避免这种情况,您可能需要使用Swing Timer :
Timer timer = new Timer(50, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if(!stop) { gamePanel.repaint(); } else { ((Timer)e.getSource()).stop(); } } }); timer.setRepeats(true); timer.setDelay(50); timer.start();
stop
是一个布尔标志,表示动画必须停止。
最有可能的是,方法move()
的for
循环运行得如此之快,以至于没有看到任何转换。 解决此问题的最简单方法是在move()
方法中在循环内添加sleep,例如:
public void move(int x, int y) { int curX = this.x; //the entire class extends rectangle int curY = this.y; // animate the movement to place for (int i = curX; i > x; i--) { this.x = i; Thread.sleep(20); // Just experiment with other sleep amounts } this.x = x; this.y = y; }
关于重绘逻辑,在每个循环中使用单独的线程重绘所有内容通常是低效的,主要是因为您可能正在重新绘制实际上没有更改的内容。 通常更新只更新变化的东西更有效。
在一个复杂的情况下,几个形状相互重叠,你需要确定哪些变化和哪些不变,因为如果某些东西不移动但是被某些东西重叠,你需要更新重叠的形状确保正确绘制。 有一些软化的algortihms可以解决这个问题,但是如果你的场景没有很多形状,那么当某些东西发生变化时重新绘制一切就更简单了。