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

时间:2015-06-02 08:58:06

标签: java swing timer jpanel paintcomponent

我有两个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但它会引发异常。

我也试过使用摆动计时器,也许我不知道如何使用它们就是我使用计时器的方式:

在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的方法(在每次迭代时调用它来绘制新面板),在使用Timers之前,它与MyActionListener类的actionPerformed具有相同的代码,现在:

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

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

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

    timer.stop();
}

这个问题有解决方案吗?

1 个答案:

答案 0 :(得分:0)

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