正如我在较早的文章中与Inerdia讨论的那样, 当我在某些JPanel中(肯定是EDT- 我已通过方法check进行检查)时,仍然有些奇怪,然后我调用了一些动画线程(该线程扩展Thread)以在内部启动通过检查我不在EDT上的线程。 所以我想我应该是因为动画应该在EDT上,所以我用runnable和invokeAndWait()包装了animate方法,但是仍然在动画线程中得到了我不在EDT上的信息,同时像我之前所说的那样调用了该代码是在EDT上,所以,我的invokeLater似乎不将该动画放在EDT上?这是为什么?
相关代码(在将animate方法与runnable包装在一起并传递给以后调用: 因此,在JPanel上有一行:
Animate(trainRailRoadTrack);
实现是:
void Animate(ArrayList<RailroadSquare> i_TrainRailRoadTrack) { ArrayList<JPanelRailoadSquare> playerRailoadPanelsTrack = getRelevantRailroads(i_TrainRailRoadTrack); new SuspendedAnimation(playerRailoadPanelsTrack).start(); jPanelBoard1.GetGameManager().EmptyPlayerSolution(); } private class SuspendedAnimation extends Thread { private ArrayList<JPanelRailoadSquare> m_PlayerRailoadPanelsTrack; public SuspendedAnimation(ArrayList<JPanelRailoadSquare> i_PlayerRailoadPanelTrack) { m_PlayerRailoadPanelsTrack = i_PlayerRailoadPanelTrack; } @Override public void run() { m_IsAnimationNeeded = true; for (JPanelRailoadSquare currRailoadSquare: m_PlayerRailoadPanelsTrack) { System.out.println("Is on Event dispatch thread: "+SwingUtilities.isEventDispatchThread()); currRailoadSquare.SetGoingTrain(); repaint(); try { Thread.sleep(150); } catch (InterruptedException e){} currRailoadSquare.UnSetGoingTrain(); repaint(); } }
SuspendedAnimation.run()您的内心 并不 在EDT上。那是您需要使用的地方invokeLater(),而不是在调用时Animate():
SuspendedAnimation.run()
invokeLater()
Animate()
@Override public void run() { // We're outside the EDT in most of run() m_IsAnimationNeeded = true; for (JPanelRailoadSquare currRailoadSquare: m_PlayerRailoadPanelsTrack) { SwingUtilities.invokeAndWait(new Runnable() { // The code that "talks" to Swing components has to be put on // the EDT currRailoadSquare.SetGoingTrain(); repaint(); }); // We want to keep sleeping outside the EDT. try { Thread.sleep(150); } catch (InterruptedException e){} SwingUtilities.invokeAndWait(new Runnable() { currRailoadSquare.UnSetGoingTrain(); repaint(); } } }