Java Swing:jLabel.setText调用太晚

Java Swing:jLabel.setText调用太晚,java,swing,Java,Swing,本人有以下申请: 一个JTextField用于用户输入 一个JLabel fro显示忙碌状态 一个JTextArea用于打印搜索结果 我希望用户将文本写入文本字段,按enter键并查看结果。我有这样的听众: private void searchForPattern(java.awt.event.ActionEvent evt) { textArea.setText(""); busyLabel.setText("Searchnig ...");

本人有以下申请:

  • 一个JTextField用于用户输入
  • 一个JLabel fro显示忙碌状态
  • 一个JTextArea用于打印搜索结果
我希望用户将文本写入文本字段,按enter键并查看结果。我有这样的听众:

private void searchForPattern(java.awt.event.ActionEvent evt) {
        textArea.setText("");
        busyLabel.setText("Searchnig ...");
        doSearch();
        busyLabel.setText("Idle");
    }
new Thread(
   new Runnable(){
      public void run(){
         searchForPattern(....)
      }
    }
  ).start();
doSearch中,有一个相当复杂的算法,它打开大量XML文件并搜索给定的模式,这需要一些时间。busyLabel的文本已更改为搜索。。。只有在doSearch完成之后。doSearch中没有第二个线程,只有很多IO操作


如何解决这个问题?

您遇到了一个典型的Swing并发问题(教程:),doSearch正在处理Swing事件线程。由于Swing在该线程中进行所有绘制/绘制并与用户交互,因此,如果它被代码占用了相当长的时间来完成,则整个应用程序将“冻结”,没有组件得到更新,所有用户交互都将被忽略

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

i、 e

private void searchForPattern(java.awt.event.ActionEvent evt){
textArea.setText(“”);
busyLabel.setText(“搜索…”);
新SwingWorker(){
@凌驾
受保护的Void doInBackground()引发异常{
doSearch();
返回null;
}
@凌驾
受保护的void done(){
busyLabel.setText(“空闲”);
}
}.execute();
}

您遇到了一个典型的Swing并发问题(教程:),doSearch正在处理Swing事件线程。由于Swing在该线程中进行所有绘制/绘制并与用户交互,因此,如果它被代码占用了相当长的时间来完成,则整个应用程序将“冻结”,没有组件得到更新,所有用户交互都将被忽略

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

i、 e

private void searchForPattern(java.awt.event.ActionEvent evt){
textArea.setText(“”);
busyLabel.setText(“搜索…”);
新SwingWorker(){
@凌驾
受保护的Void doInBackground()引发异常{
doSearch();
返回null;
}
@凌驾
受保护的void done(){
busyLabel.setText(“空闲”);
}
}.execute();
}

您还可以使用SwingUtilities的方法从应用程序线程更新GUI swing组件

private void searchForPattern(java.awt.event.ActionEvent evt) {

  SwingUtilities.invokeLater(
    new Runnable(){
      public void run(){        
         textArea.setText("");
         busyLabel.setText("Searchnig ...");
      }
    }
  );

  doSearch();

  SwingUtilities.invokeLater(
    new Runnable(){
      public void run(){
         busyLabel.setText("Idle");
      }
    }
  );
}
编辑 PS:这里我假设您没有从EDT调用searchForPattern()函数,这意味着如果您从ActionListener调用它,您必须这样调用:

private void searchForPattern(java.awt.event.ActionEvent evt) {
        textArea.setText("");
        busyLabel.setText("Searchnig ...");
        doSearch();
        busyLabel.setText("Idle");
    }
new Thread(
   new Runnable(){
      public void run(){
         searchForPattern(....)
      }
    }
  ).start();

您还可以使用SwingUtilities的方法从应用程序线程更新GUI swing组件

private void searchForPattern(java.awt.event.ActionEvent evt) {

  SwingUtilities.invokeLater(
    new Runnable(){
      public void run(){        
         textArea.setText("");
         busyLabel.setText("Searchnig ...");
      }
    }
  );

  doSearch();

  SwingUtilities.invokeLater(
    new Runnable(){
      public void run(){
         busyLabel.setText("Idle");
      }
    }
  );
}
编辑 PS:这里我假设您没有从EDT调用searchForPattern()函数,这意味着如果您从ActionListener调用它,您必须这样调用:

private void searchForPattern(java.awt.event.ActionEvent evt) {
        textArea.setText("");
        busyLabel.setText("Searchnig ...");
        doSearch();
        busyLabel.setText("Idle");
    }
new Thread(
   new Runnable(){
      public void run(){
         searchForPattern(....)
      }
    }
  ).start();

@不客气。不过,如果您要进行任何Swing编码,请务必阅读本教程,因为它包含了一些基本信息。Thanx,是的,我并不打算进行Swing编码,但如果我必须更频繁地使用Swing,我一定会阅读一些文档来了解Swing是如何工作的。@Xorty:不客气。如果你要做任何Swing编码,请务必阅读本教程,因为它包含基本信息。Thanx,是的,我并不打算做Swing编码,但是如果我必须经常使用swing,我肯定会阅读一些文档来了解swing是如何工作的。上面的代码可能不适合OP当前的问题。在EDT上调用
searchForPattern(…)
方法的可能性大于95%,事实上,根据JButton的ActionEvent参数和原始海报对问题的描述,该方法似乎是从JButton的ActionListener调用的。如果是这样,那么您的建议将导致在EDT上调用
doSearch()
,这正是不应该做的。您有权利我忘了提到他必须调用
searchForPattern(…)如果他从ActionListener调用新线程中的
方法,则可能需要编辑答案并显示此线程。这将使这成为一个有效的答案,因为这几乎是SwingWorker为您所做的事情,但是SwingWorker有一些方便的方法,比如发布和处理,可以促进所有这些。上面的代码可能不适合OP当前的问题。在EDT上调用
searchForPattern(…)
方法的可能性大于95%,事实上,根据JButton的ActionEvent参数和原始海报对问题的描述,该方法似乎是从JButton的ActionListener调用的。如果是这样,那么您的建议将导致在EDT上调用
doSearch()
,这正是不应该做的。您有权利我忘了提到他必须调用
searchForPattern(…)如果他从ActionListener调用新线程中的
方法,则可能需要编辑答案并显示此线程。这将使这成为一个有效的答案,因为这几乎是SwingWorker为您所做的事情,但是SwingWorker有一些方便的方法,比如发布和处理,可以促进所有这些。