Java Jpanel仅在完成代码后更新

Java Jpanel仅在完成代码后更新,java,observer-pattern,Java,Observer Pattern,我的JPanel有问题。我构建了一个带有界面的html/css刮板。该接口有一个JTextArea,它使用scraper完成的步骤进行更新,如“找到HTML”和“成功保存文件”。我想在代码运行时将这些消息添加到JTextArea。一个简单的检查显示更新正在使用observerpattern,但是在所有代码完成之前,所有消息都不会显示 可观察类的示例代码(触发100次): observer类的示例代码: public class ScraperView extends JPanel impleme

我的JPanel有问题。我构建了一个带有界面的html/css刮板。该接口有一个JTextArea,它使用scraper完成的步骤进行更新,如“找到HTML”和“成功保存文件”。我想在代码运行时将这些消息添加到JTextArea。一个简单的检查显示更新正在使用observerpattern,但是在所有代码完成之前,所有消息都不会显示

可观察类的示例代码(触发100次):

observer类的示例代码:

public class ScraperView extends JPanel implements Observer {
    Scraper scraper;
    public ScraperView(Scraper scraper){
        this.scraper = scraper;
        scraper.addObserver(this);
        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        refresh();
    }

    private void refresh() { 
        System.out.println("TrIGGER");
        removeAll(); 
        int removedClasses = scraper.getRemovedClasses();
        int totalClasses = scraper.getTotalClasses();
        JLabel classesText = new JLabel("   Total Classes:       "+ Integer.toString(totalClasses));
        JLabel removedClassesText = new JLabel("   Removed Classes: "+ Integer.toString(removedClasses));
        this.add(classesText);
        this.add(removedClassesText);
        this.revalidate();
        this.repaint();
    }
    @Override
    public void update(Observable o, Object arg) {
        refresh();
    }
}

有没有办法等到jPanel被更新?我注意到代码每次都会被触发,但不会更新。

你应该看看SwingWorker类,它设计用来在线程中执行任务,同时更新UI。

你每次更新都在创建和添加新的JLabel,这是个坏主意,你应该创建一次标签,然后更新它们,您还应该确保在可以使用的UI线程上更新它们


我建议您切换到JavaFX,Swing应该被弃用。如果必须使用Swing,请将逻辑移到另一个线程,该线程可以定期更新UI。您的代码正在
事件调度线程(EDT)
上执行,并且Swing在所有代码执行完毕之前无法重新绘制自身。您的代码需要在单独的线程中运行。阅读上的Swing教程中的部分。更多信息
public class ScraperView extends JPanel implements Observer {
    Scraper scraper;
    public ScraperView(Scraper scraper){
        this.scraper = scraper;
        scraper.addObserver(this);
        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        refresh();
    }

    private void refresh() { 
        System.out.println("TrIGGER");
        removeAll(); 
        int removedClasses = scraper.getRemovedClasses();
        int totalClasses = scraper.getTotalClasses();
        JLabel classesText = new JLabel("   Total Classes:       "+ Integer.toString(totalClasses));
        JLabel removedClassesText = new JLabel("   Removed Classes: "+ Integer.toString(removedClasses));
        this.add(classesText);
        this.add(removedClassesText);
        this.revalidate();
        this.repaint();
    }
    @Override
    public void update(Observable o, Object arg) {
        refresh();
    }
}
public class ScraperView extends JPanel implements Observer {
    Scraper scraper;
    JLabel classesText = new JLabel();
    JLabel removedClassesText = new JLabel();

    public ScraperView(Scraper scraper){
        this.scraper = scraper;
        scraper.addObserver(this);
        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        this.add(classesText);
        this.add(removedClassesText);
        refresh();
    }

    private void refresh() { 
        System.out.println("TrIGGER");
        int removedClasses = scraper.getRemovedClasses();
        int totalClasses = scraper.getTotalClasses();
        classesText.setText("   Total Classes:       "+ Integer.toString(totalClasses));
        removedClassesText.setText("   Removed Classes: "+ Integer.toString(removedClasses));
    }
    @Override
    public void update(Observable o, Object arg) {
        SwingUtilities.invokeLater(this::refresh);
    }
}