For Java developers, it’s very common for using these well-known statements:

System.out.print("something");
System.out.println("one more thing");
to print some text on the standard output console for the purpose of debugging and testing. However, there would be some cases in which we want the text goes into a Swing component such as a JTextArea, rather than into the standard output console. This article describes how to make that possible with a small example program.

The main idea is based on the two methods provided by the System class:

    • System.setOut(PrintStream): Re-assigns the standard output stream.
    • System.setErr(PrintStream): Re-assigns the standard error output stream.
Create a sub class of OutputStream class like this:

package net.codejava.swing;

import java.io.IOException;
import java.io.OutputStream;

import javax.swing.JTextArea;

/**
 * This class extends from OutputStream to redirect output to a JTextArrea
 * @author www.codejava.net
 *
 */
public class CustomOutputStream extends OutputStream {
	private JTextArea textArea;
	
	public CustomOutputStream(JTextArea textArea) {
		this.textArea = textArea;
	}
	
	@Override
	public void write(int b) throws IOException {
		// redirects data to the text area
        textArea.append(String.valueOf((char)b));
        // scrolls the text area to the end of data
        textArea.setCaretPosition(textArea.getDocument().getLength());
	}
}
 

As we can see, the constructor takes a JTextArea object as argument and overrides the write(int) method from the OutputStream class. In the write() method, we convert the byte to a character and append it to the JTextArea. So everything written to this output stream will be placed into the text area. Then we can re-assign the standard output streams as follows:

JTextArea textArea = new JTextArea(50, 10);
PrintStream printStream = new PrintStream(new CustomOutputStream(textArea)); 
System.setOut(printStream);
System.setErr(printStream);
If we still want to use the standard output streams, we have to keep references to them before re-assigning, for example:

PrintStream standardOut = System.out;
PrintStream standardErr = System.err; 
Following is a sample Swing program that displays a text area with two buttons:

demo program



Clicking on Start button will start a new thread which prints a log statement for every one second. The Clear button will clear the text area. 

Here is code of the program:

package net.codejava.swing;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.PrintStream;
import java.util.Date;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;

public class TextAreaLogProgram extends JFrame {
	/**
	 * The text area which is used for displaying logging information.
	 */
	private JTextArea textArea;
	
	private JButton buttonStart = new JButton("Start");
	private JButton buttonClear = new JButton("Clear");
	
	private PrintStream standardOut;
	
	public TextAreaLogProgram() {
		super("Demo printing to JTextArea");
		
		textArea = new JTextArea(50, 10);
		textArea.setEditable(false);
		PrintStream printStream = new PrintStream(new CustomOutputStream(textArea));
		
		// keeps reference of standard output stream
		standardOut = System.out;
		
		// re-assigns standard output stream and error output stream
		System.setOut(printStream);
		System.setErr(printStream);

		// creates the GUI
		setLayout(new GridBagLayout());
		GridBagConstraints constraints = new GridBagConstraints();
		constraints.gridx = 0;
		constraints.gridy = 0;
		constraints.insets = new Insets(10, 10, 10, 10);
		constraints.anchor = GridBagConstraints.WEST;
		
		add(buttonStart, constraints);
		
		constraints.gridx = 1;
		add(buttonClear, constraints);
		
		constraints.gridx = 0;
		constraints.gridy = 1;
		constraints.gridwidth = 2;
		constraints.fill = GridBagConstraints.BOTH;
		constraints.weightx = 1.0;
		constraints.weighty = 1.0;
		
		add(new JScrollPane(textArea), constraints);
		
		// adds event handler for button Start
		buttonStart.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				printLog();
			}
		});
		
		// adds event handler for button Clear
		buttonClear.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				// clears the text area
				try {
					textArea.getDocument().remove(0, 
							textArea.getDocument().getLength());
					standardOut.println("Text area cleared");
				} catch (BadLocationException ex) {
					ex.printStackTrace();
				}
			}
		});
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(480, 320);
		setLocationRelativeTo(null);	// centers on screen
	}
	
	/**
	 * Prints log statements for testing in a thread
	 */
	private void printLog() {
		Thread thread = new Thread(new Runnable() {
			@Override
			public void run() {
				while (true) {
					System.out.println("Time now is " + (new Date()));
					try {
						Thread.sleep(1000);
					} catch (InterruptedException ex) {
						ex.printStackTrace();
					}
				}
			}
		});
		thread.start();
	}
	
	/**
	 * Runs the program
	 */
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				new TextAreaLogProgram().setVisible(true);
			}
		});
	}
}
 

Other Java Swing Tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He started programming with Java in the time of Java 1.4 and has been falling in love with Java since then. Make friend with him on Facebook and watch his Java videos you YouTube.



Attachments:
Download this file (CustomOutputStream.java)CustomOutputStream.java[Java source code]0.6 kB
Download this file (TextAreaLogProgram.java)TextAreaLogProgram.java[Java source code]3 kB

Add comment

   


Comments 

#15Rodrigo2019-09-05 18:46
Helped a lot......Is it possible to keep the output both in JTextArea and the standard? How to achieve?
Quote
#14Dinkar2018-07-02 18:47
Excellent program-- most useful. Thank you
Quote
#13gadmouh2018-05-04 09:24
Works fine and perfectly, thank you very much,
Quote
#12Cameron Smith2017-08-31 00:03
thankyou!!!!!!!!!
thankyou!!!!!!!!!
Quote
#11eu2016-10-06 03:08
nice source code
i will use it many times from now on
Quote