我有一些问题与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();
}
该动画我的性格,但如此之快,我们可以看到一个东西,我怎么能做到,观看动画?
答案已经被乔纳斯(使用一个Swing计时器)给出的,但它可能是解释为什么你看不到动画有用,为什么计时器是这个问题的最佳解决方案。
为什么我没有看到不同的重绘
当你打电话JComponent#repaint
的JComponent
未重新绘制。 相反,重画的特定成分的异步请求被调度上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
教程到乔纳斯已经链接包含更多的信息。
不延长JFrame
,创建JFrame
作为局部变量
不使用KeyListener
,使用KeyBindings
,而不是
不直接画到JFrame
,使用drawImage()
到JLabel
或JComponent/JPanel
该动画我的性格,但如此之快,我们可以看到一个东西,我怎么能做到,观看动画?
另一个问题KeyListener
,你要为延迟设置中间人2周KeyEvents
您可以使用一个Swing定时器和更新定期动画。 请参阅如何使用Swing计时器