我的代码如下:
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时,不是在循环的每次迭代后更新文本区域,而是在完成任务的所有运行时,它似乎只更新文本。为什么会发生这种情况,我该如何解决?
答案 0 :(得分:3)
您可能正在使用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);
}
}
});
}
答案 1 :(得分:3)
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
}
});
}
答案 2 :(得分:2)
您正在使用称为初始线程的swing基本线程。请改用工作线程。尝试将SwingWorker用于工作线程。
有关详细信息,请浏览以下链接: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html
答案 3 :(得分:0)
正如帖子所说,重要的是不要阻止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);
}
});
}
答案 4 :(得分:0)
在自己的线程中运行 DoEverything() 的主体:
class SimplifiedClass extends JApplet {
private JTextArea outputText;
// Lots of methods
public void DoEverything() {
Thread thread = new Thread(new Runnable() {
public void run() {
String output = "";
for(int i = 0; i <= 10; i++) {
output += TaskObject.someLongTask(i);
outputText.setText(output);
}
}
}
}
}
答案 5 :(得分:-1)
尝试在outputText.setText(输出)
之后使用outputText.validate()
我也为我的程序尝试过这个类似的程序。出于某种原因,使用Thread.sleep(delay)
直接跟在outputText.setText("dsfgsdfg")
之后,即使使用outputText.validate()
也不允许用户查看输出。这是最奇怪的事情。就好像在尝试调用setText
方法后读取代码一样。然后点击睡眠方法,一切都变得地狱。