Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在JAVA中,当组件添加到单独的线程中时,如何立即重新绘制容器?_Java_Swing_User Interface_Animation_Event Dispatching - Fatal编程技术网

在JAVA中,当组件添加到单独的线程中时,如何立即重新绘制容器?

在JAVA中,当组件添加到单独的线程中时,如何立即重新绘制容器?,java,swing,user-interface,animation,event-dispatching,Java,Swing,User Interface,Animation,Event Dispatching,我正在使用java。 我有一个点击事件,在循环中向容器添加“正方形”。我希望每个方块在添加时都能正确显示。我尝试在一个单独的线程中运行“添加方块”,但它不起作用 下面是我用于“公共类GUI控制器实现ActionListener,MouseListener”的一些代码: @Override public void mouseClicked(MouseEvent e) { //createBoardPane(); new Thread ( new Runnab

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

下面是我用于“公共类GUI控制器实现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
        }
    }
}
@覆盖
公共无效mouseClicked(MouseEvent e)
{
//createBoardPane();
新线程
(
新的Runnable()
{
公开募捐
{
showAnimation();
}
}
).start();
}
公共动画
{   
对于(int i=0;i

感谢您的帮助

创建一个单独的
线程
来运行这个长时间的运行任务是一个很好的主意-除非您想在制作动画时锁定与GUI的交互

现在,Swing GUI对象不是线程安全的(只有少数例外),因此您不能从Swing的事件分派循环的线程以外的线程使用它们。因此,在for循环中获取所有GUI更新代码,并用新的Runnable(是的,另一个)将其包装起来。 然后在循环的每次迭代中使用
Runnable
调用
SwingUtilities.invokeLater(Runnable-doRun)

然后,您的GUI更新代码将被安排在事件调度循环上尽快运行,这将在您的工作线程进入睡眠状态时发生(您是否有任何反对
thread.sleep
?)

替代方法:使用
SwingWorker
而不是
Thread
并发布它(SwingWorker)将导致在事件分派循环的线程上运行的数据。您将用代码覆盖
doInBackground
。调用带有参数的
publish
,将其推入事件调度线程。使用代码覆盖
process
,以处理这些参数并更新GUI

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