java – Swing事件处理程序中无闪烁的JComponent渲染

我正在编写一个简单的
Java Swing应用程序,它被设计为课程的演示.该程序的目的是可视化递归方法的进度(特别是迷宫的递归解决方案).我希望能够在递归方法执行时更新JComponent的外观,因此从Swing的角度来看,不能从Timer类中单独触发更新,我收集的是动画的常用方法.

我的第一个想法只是在我想重绘可视化时调用repaint().但是递归方法本身是在JButton的事件处理程序中调用的,这意味着对repaint()的所有调用都会被延迟,直到事件处理程序终止 – 而我所看到的只是动画的最后一帧.如果我调用update(),我发现我可以立即将绘图发生,如下所示:

getRootPane().getContentPane().update(getGraphics());
try {
    Thread.sleep(25);
} catch (Exception e) {
}

除了动画闪烁之外,这几乎可以工作.我知道Swing是双缓冲的,但显然getGraphics给了我主动缓冲区而不是后台缓冲区.我看不到任何方法可以让我访问后台缓冲区.

所以我正在寻找一种解决方案,允许我在递归过程中重新绘制组件并给我一个无闪烁的动画.有没有办法在执行事件处理程序时激活内置双缓冲?尝试实现我自己的缓冲系统会更好吗?或者我正在尝试做什么只是不可能/建议使用Swing?

(最后一点,这是我在这里发表的第一篇文章.我试过写一个好问题,但如果我遗漏了什么,请告诉我很好的事情,下次我会尽力做得更好.谢谢!)

最佳答案 首先,你应该
not be executing long-running actions in the Event Dispatch Thread,我认为这是你的动画闪烁的一个原因.

因此,我建议在按下按钮时启动一个执行递归方法的线程(并且可能会在完成工作之前将其停用).

要渲染动画,您可以在递归方法中调用myComponent.repaint(),也可以启动Swing Timer(感谢@mKorbel将其解析出来),它基本上如下所示:

ActionListener repaintTrigger = new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
          myComponent.repaint();
      }
};
new Timer(25, repaintTrigger).start();

我推荐后一种方法,因为你的递归方法可能不应该知道关于Swing组件的任何信息(除非你通过“ProgressListener”或其他东西将它解耦).

因为看起来你不仅仅是初学者,我只是给了一些关于该怎么做的提示.如果您需要更多输入,请随时询问.

点赞