在完成其他操作之前,图形文本不会更新



我有一个JButton,它在点击时执行一个动作。在操作执行中,我想在调用包含大量计算的 NotifyObserver 之前更新按钮文本。问题是,在 NotifyObserver 调用的所有操作完成之前,按钮文本不会更新。以下是 JButton 操作代码:

//Action for sinoButton
sinoButton.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
        sinoButton.setText("Loading Sinogram"); //Set text while loading sinogram
        NotifyObserversSinogram(); //Notify observer and start sinogram calculation
    }
});

如您所见,应在通知观察者之前更新按钮文本。关于如何解决这个问题的任何想法?

如果NotifyObserversSinogram()不执行特定于 Swing 的计算,只需将其放在另一个线程中:

 public void actionPerformed(ActionEvent e) {
    sinoButton.setText("Loading Sinogram");
    new Thread() {
        public void run(){
            NotifyObserversSinogram();
        }
    }.start();
}

如果是,请参阅SwingWorker

编辑由于 Swing 不是线程安全的,因此您必须使用 Swingutilities:

JButton b = new JButton("Run query");
b.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {
    Thread queryThread = new Thread() {
      public void run() {
        runQueries();
      }
    };
    queryThread.start();
  }
});

// Called from non-UI thread
private void runQueries() {
  for (int i = 0; i < noQueries; i++) {
    runDatabaseQuery(i);
    updateProgress(i);
  }
}
private void updateProgress(final int queryNo) {
  SwingUtilities.invokeLater(new Runnable() {
    public void run() {
      // Here, we can safely update the GUI
      // because we'll be called from the
      // event dispatch thread
      statusLabel.setText("Query: " + queryNo);
    }
  });
}

这里有一些关于它如何工作的更完整的信息: 带摆动的螺纹

Swing 是一个单线程框架,ActionListener在事件调度线程的上下文中执行,这将阻止 UI 更新,直到 actionPerformed 方法存在

现在,您可以使用另一个线程来运行计算,但 Swing 也不是线程安全的。

一个简单的解决方案是使用 SwingWorker ,它有办法安全地更新 UI,提供进度更新,并在工作人员done时收到通知

有关更多详细信息,请参阅 Swing 和工作线程中的并发和 SwingWorker

JButton sinoButton = new JButton();
  //Action for sinoButton
    sinoButton.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub
            ((JButton)e.getSource()).setText("Loading Sinogram"); //Set text while loading sinogram
           /*Since this is time consuming operation running on EDT its causing the issue.
            * To fix it run the time consuming operation in a thread other than EDT
            * */
            new Thread(){
                public void run() {
                    NotifyObserversSinogram();
                };
            }.start();
        }
    });

最新更新