时序与Swing动画 [英] Timing with Swing animation
问题描述
我有一些问题,Swing和动画一个角色,
我有钥匙监听一个JFrame,当用户打不下来,在这里叫我的JPanel方法
i have some problems with Swing and animate a character, I Have a JFrame with key listener and when the user hit down,it calls my JPanel method here
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();
}
这动画我的性格,但如此之快,我们可以看到一个东西,我怎么能做到,观看动画?
This animate my character but so fast that we can see a thing,how do i can do to view the animation?
推荐答案
答案已经被乔纳斯给出(使用一个Swing定时器),但它可能是有用的解释为什么你看不到动画,以及为什么计时器针对此问题的最佳解决方案。
The answer is already given by Jonas (use a Swing timer), but it might be useful to explain why you are not seeing the animation, and why the timer is the best solution for this problem.
为什么我看不到不同重绘
当你调用的JComponent#重绘
的的JComponent
未重新绘制。相反,重新绘制了一定分量的异步请求定于美国东部时间的。如果调用许多重绘
通话,摇摆可能会决定小组的请求,并重绘组件只有一次。
When you call JComponent#repaint
the JComponent
is not repainted. Instead, an asynchronous request to repaint a certain component is scheduled on the EDT. If you invoke many repaint
calls, Swing might decide to group those requests and repaint the component just once.
我没有立刻找到Oracle文档在此官方引用(的画秋千文章,似乎并没有提到它)。在那里,我发现这个问题的唯一地方是在这篇文章一张纸条,但我是pretty确定这是什么地方记录。
I did not immediately found an official reference for this in the Oracle documentation (the Swing painting article does not seem to mention it). The only place where I found this was in a note in this article, but I am pretty certain this is documented somewhere.
为什么使用定时
最好的解决方案
Why is using a Timer
the best solution
有关的动画,你基本上想说:
For an animation, you basically want to say:
我的性格应该移动 X
在Ÿ像素
毫秒
my character should move
x
pixels iny
milliseconds
和preferably,你想有一个在屏幕上流畅的动画,所以你需要相当频繁地重绘。如果你记住,
And preferably, you want to have a smooth animation on screen so you need to repaint rather frequently. If you keep in mind that
- 与Swing组件应该发生在美国东部时间(事件指派线程的所有交互,请参见并发在Swing 文章获取更多信息)
- 您永远不应该阻止EDT,因为这将冻结您的UI,这意味着你不能等待在EDT直到重绘完成或重绘不会发生
- 重绘请求可以分组,因此调用重绘
X
时间并不能保证你,你的油漆
方法被调用X
时间以及
- All interaction with the Swing components should happen on the EDT (Event Dispatch Thread, see the Concurrency in Swing article for more info)
- You should never block the EDT as this will freeze your UI, meaning you cannot 'wait' in the EDT until a repaint is done or the repaint will never happen
- Repaint requests can be grouped, so calling repaint
x
times does not guarantee you that yourpaint
method is calledx
times as well
要克服这种局限性的解决方案是使用定时
。在相同的例子(移动屏幕上的字符),你可以使用定时
来更新字符的位置和安排重绘。因为定时
code被触发的EDT,你不违反Swing线程规则。
The solution to overcome this limitations is to use a Timer
. With the same example (moving a character on screen), you can use a Timer
to update the position of the character and schedule a repaint. Since the Timer
code is triggered on the EDT, you do not violate the Swing threading rules.
在组件的的paintComponent
方法,你再在当前位置绘制的字符。这可能取决于有多少次定时
已触发的previous 油漆
呼叫和电流油漆
通话之间。这将确保在该角色的动作是独立于系统的速度。只有动画的平滑度将取决于您的系统。(如:有多少重绘请求获得分组)
In the paintComponent
method of your component, you then paint the character at the current location. This might be the 'previous location + 1', or the 'previous location +2' (or ...) depending on how many times the Timer
has been triggered between the previous paint
call and the current paint
call. This ensures the speed at which your character moves is system-independent. Only the smoothness of the animation will depend on your system (as in: how many repaint requests get grouped).
The Swing Timer
tutorial to which Jonas already linked contains more information.
这篇关于时序与Swing动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!