为什么我的JTextArea没有更新?

我的代码如下:

class SimplifiedClass extends JApplet { private JTextArea outputText; // Lots of methods public void DoEverything() { String output = ""; for(int i = 0; i <= 10; i++) { output += TaskObject.someLongTask(i); outputText.setText(output); } } } 

但是,当调用setText时,不是在循环的每次迭代之后更新文本区域,而是在完成任务的所有运行时它似乎仅更新文本。 为什么会发生这种情况,我该如何解决?

您可能正在使用Swing线程,它等待您的代码在更新UI之前执行。 尝试为该循环使用单独的线程。

 public void DoEverything() { SwingUtilities.invokeLater(new Runnable() { public void run() { String output = ""; for(int i = 0; i <= 10; i++) { output += TaskObject.someLongTask(i); outputText.setText(output); } } }); } 
 private JTextArea outputText = new JTextArea(); public void DoEverything() { String output = ""; for(int i = 0; i <= 10; i++) { output += TaskObject.someLongTask(i); appendNewText(output); } } public void appendNewText(String txt) { SwingUtilities.invokeLater(new Runnable() { public void run() { outputText.setText(outputText.getText + txt); //outputText.setText(outputText.getText + "\n"+ txt); Windows LineSeparator } }); } 

您正在使用称为初始线程的swing基本线程。 请改用工作线程。 尝试将SwingWorker用于工作线程。

有关更多详细信息,请访问以下链接: http : //docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html

正如post所说,重要的是不要阻止EDT(Event Dispatch Thread)。 在我的例子中,实际工作从EDT线程开始,因为它是从按钮单击ActionListener。 我需要用一个单独的线程包装它,以便它与Event Dispatch Thread分开。 因此EDT不会被阻止。

另请注意,从单独的线程更新UI时,需要使用SwingUtilities.invokeLater()。 下面的代码示例与我的原始代码略有简化。 我实际上是使用多个线程并行执行多个任务,并且在每个线程中调用updateProgress()以通过附加最新状态来更新TextArea。

完整的源代码在这里: https : //github.com/mhisoft/rdpro/blob/master/src/main/java/org/mhisoft/rdpro/ui/ReproMainForm.java

 btnOk.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { //Don't block the EDT, wrap it in a seperate thread DoItJobThread t = new DoItJobThread(); t.start(); } }); class DoItJobThread extends Thread { @Override public void run() { //do some task // output the progress updateProgress(); } } public void updateProgress(final String msg) { //invokeLater() //This method allows us to post a "job" to Swing, which it will then run // on the event dispatch thread at its next convenience. SwingUtilities.invokeLater(new Runnable() { public void run() { // Here, we can safely update the GUI // because we'll be called from the // event dispatch thread outputTextArea.append(msg); outputTextArea.setCaretPosition(outputTextArea.getDocument().getLength()); //labelStatus.setText(msg); } }); } 

尝试在outputText.setText(输出)之后使用outputText.validate()

我也尝试过这个类似的程序。 由于某些原因,直接在outputText.setText("dsfgsdfg")之后使用Thread.sleep(delay) ,即使使用outputText.validate()也不允许用户查看输出。 这是最奇怪的事情。 就好像在尝试调用setText方法之后读取代码一样。 然后点击睡眠方法,这一切都变成了地狱。