简体   繁体   English

如何在ActionListener正在进行时更新swing UI

[英]How to update swing UI while ActionListener is in progress

In my code below I want the TextArea to be cleared while the application is loading data. 在我的下面的代码中,我希望在应用程序加载数据时清除TextArea。 I also added a repaint() but still it's not cleared. 我还添加了一个重绘()但仍然没有清除。 Do I have to notify it differently to force a repaint? 我是否必须以不同方式通知它以强制重画?

    button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent event) {
            textArea.setText("");
            textArea.repaint();


            String result = //call a REST API
            textArea.setText(result);
        }
    });

What I think you want to do is calling the rest api in another Thread. 我认为你想做的是在另一个线程中调用其余的api。 You can do it with a SwingWorker that is designed to run heavily task in another thread without blocking the gui. 您可以使用SwingWorker来实现它,该SwingWorker旨在在不阻止gui的情况下在另一个线程中运行大量任务。 Here is a complete example i really like Swing Worker Example 这是一个完整的例子,我非常喜欢Swing Worker Example

Example: 例:

class Worker extends SwingWorker<Void, String> {

    @Override
    protected Void doInBackground() throws Exception {
       //here you make heavy task this is running in another thread not in EDT
       // call REST API here

      return null;
    }

   @Override
   protected void done() {
        //this is executed in the EDT
        //here you update your textArea with the result
   }
}

After the doInBackground method is finished the done method is executed. doInBackground方法完成后,执行done方法。 Then SwingWorker notifies any PropertyChangeListeners about the state property change to StateValue.DONE . 然后, SwingWorker StateValue.DONE任何PropertyChangeListeners状态属性更改通知给StateValue.DONE So you can override this method here or use a propertyChangeListener implementation to do what you want. 因此,您可以在此处覆盖此方法,或使用propertyChangeListener实现来执行您想要的操作。

Just do the time-consuming operation in another thread. 只是在另一个线程中执行耗时的操作。 You can use SwingWorker , which will notify AWT thread as soon as the computation completes. 您可以使用SwingWorker ,它将在计算完成后立即通知AWT线程。

public void actionPerformed(ActionEvent event) {
    textArea.setText("");

    SwingWorker<String, Object> worker = new SwingWorker<String, Object>() {
        @Override
        protected String doInBackground() throws Exception {                
            return ...; // call a REST API
        }
        @Override
        protected void done() {
            try {
                textArea.setText(get());
            } catch (Exception e) {
                //ignore
            }
        }
    };      
    worker.execute();
}

You can also use invokeLater , which will execute the REST call as a part of the event queue. 您还可以使用invokeLater ,它将作为事件队列的一部分执行REST调用。

public void actionPerformed(ActionEvent event) {
    textArea.setText("");

    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            String result = // call a REST API
            textArea.setText(result);
        }
    });
}

You run your actionPerformed(ActionEvent event) method in EDT because of that you can't update UI. 您在EDT中运行actionPerformed(ActionEvent event)方法,因为您无法更新UI。 For updating UI from your code try to use SwingWorker , it can update UI while background process running. 要从代码更新UI,请尝试使用SwingWorker ,它可以在后台进程运行时更新UI。

Or you can try to use Executors for background process and updating UI from EDT. 或者您可以尝试使用Executors进行后台处理并从EDT更新UI。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM