2

我正在使用java。我有一个单击事件,它在循环中将“正方形”添加到容器中。我希望每个方块在添加时都能正确显示。我尝试在单独的线程中运行“添加正方形”,但它不起作用。

这是我用于“公共类 GuiController 实现 ActionListener、MouseListener”的一些代码:

@Override
public void mouseClicked(MouseEvent e)
{
    //createBoardPane();
    new Thread
    (
        new Runnable() 
        {
            public void run() 
            {
                showAnimation();
            }
        }
    ).start();
}

public void showAnimation()
{   
    for(int i = 0; i < model.getAnimationList().size(); i++)
    {
        String coord = model.getAnimationList().get(i);
        int x = Integer.parseInt(coord.substring(0, coord.indexOf(',')));
        int y = Integer.parseInt(coord.substring(coord.indexOf(',') + 1, coord.length() - 2));
        boolean shouldPlacePiece = (coord.charAt(coord.length() - 1) == 'p');

        if(shouldPlacePiece)
        {
            model.getView().getBoardPane().getComponent(x + (y * model.getBoardSize())).setBackground(Color.BLACK);
        }
        else
        {
            model.getView().getBoardPane().getComponent(x + (y * model.getBoardSize())).setBackground(Color.WHITE);
        }

        model.getView().getBoardPane().repaint();

        long time = System.currentTimeMillis();
        while((System.currentTimeMillis() - time) < 250)
        {
            // wait loop
        }
    }
}

任何帮助表示赞赏!

4

1 回答 1

1

为这个长时间运行的任务创建一个单独Thread的运行是一个好主意——除非你想在做动画时锁定与 GUI 的交互。

现在,Swing GUI 对象不是线程安全的(除了少数例外),因此您不能从 Swing 的 Event Dispatch Loop 线程以外的线程使用它们。所以在你的 for 循环中获取所有的 GUI 更新代码,并用一个新的 Runnable 包装它(是的,另一个)。然后在循环的每次迭代中调用SwingUtilities.invokeLater(Runnable doRun)它。Runnable

然后,您的 GUI 更新代码将被安排在 Event Dispatch Loop 上尽快运行,这将在您的工作线程进入睡眠状态时发生(您有什么反对意见Thread.sleep吗?)。

替代方案:使用SwingWorker而不是Thread

SwingWorker 将为您创建和管理一个新线程,并发布它 (SwingWorker) 将导致在 Event Dispatch Loop 的线程上运行的数据。您将doInBackground使用您的代码覆盖。使用参数调用publish以推送到事件调度线程。使用代码覆盖process以处理这些参数并更新您的 GUI。

SwingWorker 的问题是它publish在大约 33 毫秒的时间内累积 ed 事件。如果您发布的频率高于此值,您可能每 33 毫秒左右将所有事件聚集在一起。在您的情况下,更新之间的 250 毫秒应该不是问题。

于 2012-07-30T21:05:25.007 回答