我有以下应用程序:
一个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();
}