动画线程和EDT

时间:2011-10-23 17:48:36

标签: java swing applet thread-safety event-dispatch-thread

正如我在earlier post上与Inerdia讨论的那样 有些东西仍然很奇怪当我在一些JPanel(EDT肯定 - 我用方法检查检查)然后我调用一些动画线程(线程扩展线程)启动,在线程内我不在EDT上通过检查。
所以我想我应该是因为动画应该在EDT上,所以我用runnable和invokeAndWait()包装了animate方法,但仍然在动画线程中得到了我不在EDT上,而正如我之前所说的那样调用该代码在EDT上,所以,我的invokeLater似乎没有把这个动画放在EDT上?这是为什么?

相关代码(在使用runnable包装animate方法并稍后调用之前发送:
因此,在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();                       
    }
}

1 个答案:

答案 0 :(得分:1)

SuspendedAnimation.run()内,你在EDT上不是。您需要使用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();                       
        }
    }
}