定时与Swing动画(Timing with Swing animation)

2019-06-25 14:27发布

我有一些问题与Swing和动画一个角色,我有钥匙监听器,当用户打下来一个JFrame,它要求在这里我的JPanel方法

for(int i=1;i<4;i++)
{           
    pY+=16;
    g.drawImage(perso,pX,pY,pX+50,pY+50,0+50*i,0,50+50*i,50,this 
    this.repaint();                 
}

该动画我的性格,但如此之快,我们可以看到一个东西,我怎么能做到,观看动画?

Answer 1:

答案已经被乔纳斯(使用一个Swing计时器)给出的,但它可能是解释为什么你看不到动画有用,为什么计时器是这个问题的最佳解决方案。

为什么我没有看到不同的重绘

当你打电话JComponent#repaintJComponent未重新绘制。 相反,重画的特定成分的异步请求被调度上EDT。 如果调用许多repaint电话,摇摆可能决定小组的请求,并重绘组件只有一次。

我没有立即找到Oracle文档(中这一官方参考Swing绘图文章似乎没有提到它)。 在那里,我发现这个问题的唯一地方是在一份报告中这篇文章 ,但我敢肯定这是什么地方记录。

为什么使用Timer的最佳解决方案

对于动画,你基本上想说:

我的性格应该移动x像素y毫秒

而且最好,你想有一个在屏幕上流畅的动画,所以你需要相当频繁地重新绘制。 如果你要记住,

  • 与Swing组件的所有交互都应该发生在美国东部时间(事件指派线程,看到在Swing并发文章获取更多信息)
  • 你不应该阻止EDT,因为这将会冻结您的UI,这意味着你不能“等待”在EDT直到重画已完成或重绘不会发生
  • 重绘请求可以分组,因此调用重绘x倍并不能保证你,你的paint方法被称为x倍,以及

克服这种局限性的解决方法是使用一个Timer 。 用上面的例子(移动屏幕上的字符),你可以用一个Timer来更新字符的位置和安排重绘。 由于Timer代码被触发的EDT,你不违反Swing线程规则。

paintComponent您的组件的方法,你再在当前位置绘制的字符。 这可能是“以前的位置+ 1”,或取决于有多少次了“以前的位置+2”(或......) Timer已经在以前的触发之间的paint通话和当前paint通话。 这可确保该角色移动是独立于系统的速度。 只有动画的平滑度将取决于您的系统(如:许多重绘请求得到的分组方式)。

该秋千Timer教程到乔纳斯已经链接包含更多的信息。



Answer 2:

  1. 不延长JFrame ,创建JFrame作为局部变量

  2. 不使用KeyListener ,使用KeyBindings ,而不是

  3. 不直接画到JFrame ,使用drawImage()JLabelJComponent/JPanel

  4. 该动画我的性格,但如此之快,我们可以看到一个东西,我怎么能做到,观看动画?

另一个问题KeyListener ,你要为延迟设置中间人2周KeyEvents



Answer 3:

您可以使用一个Swing定时器和更新定期动画。 请参阅如何使用Swing计时器



文章来源: Timing with Swing animation