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

标签 java swing user-interface animation event-dispatching

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

这是我用于“公共(public)类 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
        }
    }
}

感谢任何帮助!

最佳答案

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

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

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

备选方案:使用 SwingWorker 代替 Thread

SwingWorker will create and manage a new the Thread为您发布数据,它 (SwingWorker) 将导致在事件调度循环的线程上运行。您将使用您的代码覆盖 doInBackground。使用参数调用 publish 以推送到事件调度线程。使用代码覆盖 process 以处理这些参数并更新您的 GUI。

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

关于java - 当组件添加到 JAVA 的单独线程中时,如何立即重绘容器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11728953/

相关文章:

java - Java 中操作系统的名称(不是 "os.name")

java - 为什么 sysout 不起作用?

java - 在 JFrame 中的特定位置设置自定义 JPanel

java - 如何将项目从 jcombobox 转移到 mysql 表

为轻松构建基于 Web 的竞赛而设计的 JavaScript 库

带有底点的 Android ViewPager

java - 从java程序调用Stanford POS Tagger maxentTagger

java - 没有 jpa 的 Spring 和 Hibernate

java - 在 jar 文件中加载图像

android - 优化复杂布局