当我尝试在 JPanel 上绘图时应用程序冻结

Application freezes when I try to draw on a JPanel

我有两个 JPanel:

public class FirstPanel extends JPanel
public class SecondPanel extends JPanel implements Listener

FirstPanel.addListener(SecondPanel)
SecondPanel.setPanel(FirstPanel)

Listener 是一个只有一个方法的接口 update().

SecondPanel 有一个 middleLeftPanel,我想在其中放置 FirstPanel:

DesignUtils.addComponentAndConstraints(middleLeftPanel, FirstPanel, DesignUtils.createGridBagConstraint(0, 0, 1, 1, 1, 1, 0, 0, GridBagConstraints.BOTH, GridBagConstraints.CENTER, null));

我也有多次迭代(例如:10000),每次迭代后,FirstPanel 重新绘制自身并更新侦听器,在本例中仅 SecondPanel:

public void trainStepPerformed(...) {
    repaint(0, 0, getWidth(), getHeight());
    updateListeners();
}

SecondPanel 的 update() 方法:

this.validate();
this.repaint();

当我在 SecondPanel 上按下 JButton 时,我想查看 FirstPanel 如何在每次迭代时从 SecondPanel 将自身绘制到 middleLeftPanel 上,但应用程序会冻结,当最后一次迭代完成时,它会解除阻塞并仅向我显示最终的结果。我尝试使用 SwingUtilities.InvokeAndWait 但它抛出异常。

我也尝试过使用 swing 定时器,也许我不知道如何使用它们,因为我是这样使用定时器的:

在 FirstPanel 的构造函数中,我初始化了 Timer:

timer = new Timer(1, new MyActionListener());

public class MyActionListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            repaint(0, 0, getWidth(), getHeight());
            updateListeners();
        }
    }

FirstPanel 有一个名为 trainStepPerformed 的方法(每次迭代都会调用它来绘制新面板),在使用计时器之前,它与 MyActionListener class 中的 actionPerformed 具有相同的代码,现在:

@Override
    public void trainStepPerformed(...) {
        timer.start();

因为 repaint 调用 paintComponent 我认为这是停止计时器的地方:

public void paintComponent(Graphics g) {
    %rest of the code%

    timer.stop();
}

这个问题有解决办法吗?

您可能阻塞了 Swing 线程。尝试将繁重的处理工作卸载到 SwingWorker.