其他操作完成后,图形文本不会更新

时间:2015-04-28 11:48:31

标签: java swing jbutton actionlistener

我有一个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
    }
});

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

4 个答案:

答案 0 :(得分:3)

修改 由于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);
    }
  });
}

以下是一些有关其工作原理的更完整信息:Threading with swing

答案 1 :(得分:3)

如果NotifyObserversSinogram()没有进行Swing特定计算,只需将其放在另一个线程中:

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

如果是,请参阅SwingWorker

答案 2 :(得分:2)

Swing是一个单线程框架,ActionListener在Event Dispatching Thread的上下文中执行,这将阻止UI在actionPerformed方法存在之前被更新

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

一个简单的解决方案是使用SwingWorker,它可以让您安全地更新用户界面,提供进度更新,并在工作人员done时通知

有关详细信息,请参阅Concurrency in SwingWorker Threads and SwingWorker

答案 3 :(得分:0)

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