24

I am trying to create a very simple Swing UI that logs information onto the screen via a JTextArea as processing occurs in the background. When the user clicks a button, I want each call to:

textArea.append(someString + "\n");

to immediately show up in the UI.

At the moment, the JTextArea does not show all log information until the processing has completed after clicking the button. How can I get it to refresh dynamically?

Michael Myers
  • 188,989
  • 46
  • 291
  • 292
digiarnie
  • 22,305
  • 31
  • 78
  • 126

6 Answers6

48

Try this:

jTextArea.update(jTextArea.getGraphics());
Michael Mrozek
  • 169,610
  • 28
  • 168
  • 175
petr
  • 489
  • 4
  • 2
24

I ran into the same issue with my application. I had a "Run" button my application that performed some actions and outputted the results to a JTextArea. I had to call the method from a Thread. Here is what I did.

I have several radio buttons of actions that can be done, and then one "Run" button to execute that particular action. I have an action called Validate. So when I check that radio button and click the "Run" button, it calls the method validate(). So I first placed this method into an inner class that implemented Runnable

class ValidateThread implements Runnable {
    public void run() {
        validate();
    }
}

I then called this thread in the ActionListener of the "Run" button as so

runButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent ae) {
        // Some code checked on some radio buttons
        if(radioButton.isSelected()) {
            if(radioButton.getText().equals("VALIDATE")) {
               Runnable runnable = new ValidateThread();
               Thread thread = new Thread(runnable);
               thread.start();
            }
        }
    }

});

Voila! The output is now sent to the JTextArea.

Now, you will notice that the JTextArea will not scroll down with the text. So you need to set the caret position like

textArea.setCaretPosition(textArea.getText().length() - 1);

Now when the data is added to the JTextArea, it will always scroll down.

Ascalonian
  • 14,409
  • 18
  • 71
  • 103
4

As others have said this requires multithreading. Have a look at Concurrency in Swing.

One solution would be to implement the processing using a SwingWorker. The doInBackground method would implement the processing and you would invoke the publish method with the String to be appended as the argument. Your SwingWorker would then override the process method to take a String argument and append it to the text area.

Mark
  • 28,783
  • 8
  • 63
  • 92
1

I'm sorry for replying to this question that was posted 4 years ago, but I have another solution that worked for me. I just used pointers to update the JTextAreaas such:

//JScrollPane variable pane initialized with JTextArea area
//We will update area with new text
JTextArea temp = (JTextArea) pane.getViewPort().getView();
//new text to add
JTextArea c = new JTextArea();
c.append("text \n)";
//update through pointers
temp = c;
pane.validate();
0

You'll need multithreading for this. Ready to take the plunge?

Spencer Ruport
  • 34,865
  • 12
  • 85
  • 147
0

If it's multithreading you need try this! http://www.devarticles.com/c/a/Java/Multithreading-in-Java/

binarycreations
  • 3,091
  • 6
  • 32
  • 38