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

ecfdbz9o  于 2021-07-13  发布在  Java
关注(0)|答案(4)|浏览(314)

我有一个jbutton,它在单击时执行一个操作。在actionperformed中,我想在调用notifyobserver之前更新按钮文本,notifyobserver包含大量计算。问题是,在notifyobserver调用的所有操作完成之前,buttontext不会更新。以下是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
    }
});

如您所见,应该在通知观察者之前更新按钮文本。有什么办法解决这个问题吗?

svgewumm

svgewumm1#

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

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

如果有,请看 SwingWorker .

ifmq2ha2

ifmq2ha22#

编辑由于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线程

whhtz7ly

whhtz7ly3#

swing是一个单线程框架 ActionListener 是在事件调度线程的上下文中执行的,这将阻止在 actionPerformed 方法存在
现在,您可以使用另一个线程来运行计算,但是swing也不是线程安全的。
一个简单的解决方案是使用 SwingWorker ,这样您就可以安全地更新ui,提供进度更新,并在工作进程停止时收到通知 done 有关更多详细信息,请参见swing和worker线程中的并发性以及swingworker

u5i3ibmn

u5i3ibmn4#

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();
        }
    });

相关问题