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