java - Swing 动画的计时

标签 java swing animation timer

我在使用 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();                 
}

这为我的角色设置了动画,但速度太快,我们可以看到一个东西,我该如何查看动画?

最佳答案

Jonas 已经给出了答案(使用 Swing 计时器),但解释为什么您看不到动画以及为什么计时器是此问题的最佳解决方案可能会很有用。

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

当您调用JComponent#repaintJComponent没有重新粉刷。相反,重绘某个组件的异步请求会在 EDT 上安排。如果您调用许多 repaint调用时,Swing 可能会决定对这些请求进行分组并仅重绘组件一次。

我没有立即在 Oracle 文档中找到对此的官方引用(Swing painting article 似乎没有提及它)。我唯一找到这个的地方是在 this article 的注释中。 ,但我很确定这在某处有记录。

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

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

my character should move x pixels in y milliseconds

最好,您希望屏幕上有流畅的动画,因此需要经常重新绘制。如果你记住这一点

  • 与 Swing 组件的所有交互都应在 EDT 上进行(事件调度线程,请参阅 Concurrency in Swing 文章了解更多信息)
  • 您永远不应该阻止 EDT,因为这会卡住您的 UI,这意味着您无法在 EDT 中“等待”直到重绘完成,否则重绘永远不会发生
  • 重绘请求可以分组,因此调用重绘 x时代并不保证您的paint方法调用 x次也是如此

克服此限制的解决方案是使用 Timer 。对于相同的示例(在屏幕上移动角色),您可以使用 Timer更新角色的位置并安排重新绘制。自 Timer代码在 EDT 上触发,您没有违反 Swing 线程规则。

paintComponent方法,然后在当前位置绘制角色。这可能是“先前位置 + 1”或“先前位置 +2”(或...),具体取决于 Timer 的次数。已在之前的 paint 之间触发通话和当前paint称呼。这确保了角色移动的速度与系统无关。只有动画的平滑度取决于您的系统(例如:对多少个重绘请求进行分组)。

Swing Timer tutorial乔纳斯已经链接到的内容包含更多信息。

关于java - Swing 动画的计时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11088910/

相关文章:

java - Android:使用 log4j2 创建日志时获取额外的空文件

java - 问 : How to use OnClickListener with HorizontalScrollView

java - 使用 Swing 和 Threads 设计 JApplet 动画

Java:访问 Action 监听器内的变量

swift - NSFetchedResultsController 触发的动画完成后执行代码

java - 通过热键执行相应操作时动画按钮

java - 如何在 Spring Boot OIDC 应用程序的 Controller 中获取用户详细信息?

java - 初始化 JavaBean

java - 动态菜单 Java Swing

javascript - Angular 2在点击时增加动画边距