我有以下应用程序:


一个JTextField供用户输入,
一个JLabel来回显示忙碌状态,
一个JTextArea用于打印搜索结果。


我希望用户将文本写入文本字段,然后按Enter键并查看结果。我有这样的听众:

private void searchForPattern(java.awt.event.ActionEvent evt) {
        textArea.setText("");
        busyLabel.setText("Searchnig ...");
        doSearch();
        busyLabel.setText("Idle");
    }


在doSearch中,有一种相当复杂的算法,该算法会打开许多​​XML文件并搜索给定的模式,这需要一段时间。仅在doSearch完成后,busyLabel的文本才会更改为Searching...。 doSearch中没有第二个线程,只有许多IO操作。

我怎样才能解决这个问题?

最佳答案

您有一个经典的Swing并发问题(教程:Concurrency in Swing),其中doSearch占用了Swing事件线程。由于该线程是Swing进行所有绘画/绘图以及与用户交互的地方,因此,如果它被花费任何可察觉时间完成的代码所束缚,则整个应用程序将“冻结”,而没有组件得到更新并且所有用户交互被忽略。

解决方案:在诸如SwingWorker对象提供的后台线程上执行此操作。在SwingWorker的done()方法中将“ Idle”字符串设置到JLabel中。



private void searchForPattern(java.awt.event.ActionEvent evt) {
  textArea.setText("");
  busyLabel.setText("Searching ...");
  new SwingWorker<Void, Void>() {
     @Override
     protected Void doInBackground() throws Exception {
        doSearch();
        return null;
     }

     @Override
     protected void done() {
        busyLabel.setText("Idle");
     }
  }.execute();
}

09-11 17:02