I have code as follows:
class SimplifiedClass extends JApplet {
private JTextArea outputText;
// Lots of methods
public void DoEverything() {
Try using outputText.validate() after outputText.setText(output)
I tried this for my program too which is similar. For some reason using the Thread.sleep(delay)
directly following a outputText.setText("dsfgsdfg")
, even with a outputText.validate()
does not allow the user to see the output. It's the strangest thing. It is as if the code is read after the setText
method is trying to be invoked. Then hits the sleep method and it all goes to hell.
You are using swing basic threads called initial threads. Use worker threads instead. Try using SwingWorker for worker threads.
For further details, go through the following link: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html
As the post said it is important not to block the EDT (the Event Dispatch Thread). In my exmaple below the actual work starts from the EDT thread as it is from a button click ActionListener. I need to wrap it with a separate thread so it is separated from the Event Dispatch Thread. Thus the EDT is not blocked.
Also note you need to SwingUtilities.invokeLater() when update the UI from a separate Thread. The code example below is simplified a little from my original code. I am actually performing multiple tasks in parallel using multiple threads and in each of those thread the updateProgress() is called to update the TextArea by appending the latest status.
Full source code is here: 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);
}
});
}
You're probably using the Swing thread which is waiting for your code to execute before it can update the UI. Try using a separate thread for that loop.
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
}
});
}