Feb 22

We’ve all got code riddled with System.out.println() messages. We should use a logging framework, but often we’re in a rush and we end up writing to stdout because its simpler at the time.

If there are too many System.out.println() calls and we want to stop them going to the console then we can redirect stdout and stderr to a different stream using the setOut() and setErr() methods provided by the System class.

If we want to instead have them written to a Swing text component such as a JTextArea or JTextPane then what we need is an OutputStream subclass that will write to the text component.

The following code shows how that can achieved, resulting in System.out.println() call writing to your designated JTextComponent.

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

import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;

public class RedirectOutput {

	private JTextComponent textComponent;
	
	public static void sendTo(JTextComponent textComponent) {
		new RedirectOutput(textComponent).redirectSystemStreams();
	}
	
	private RedirectOutput(JTextComponent textComponent) {
		this.textComponent = textComponent;
	}
	
	private void updateTextComponent(final String text) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				Document doc = textComponent.getDocument();
				try {
					doc.insertString(doc.getLength(), text, null);
				} catch (BadLocationException e) {
					throw new RuntimeException(e);
				}
				textComponent.setCaretPosition(doc.getLength() - 1);
			}
		});
	}

	private void redirectSystemStreams() {
		OutputStream out = new OutputStream() {
			@Override
			public void write(final int b) throws IOException {
				updateTextComponent(String.valueOf((char) b));
			}

			@Override
			public void write(byte[] b, int off, int len) throws IOException {
				updateTextComponent(new String(b, off, len));
			}

			@Override
			public void write(byte[] b) throws IOException {
				write(b, 0, b.length);
			}
		};

		System.setOut(new PrintStream(out, true));
		System.setErr(new PrintStream(out, true));
	}

}

written by objects \\ tags: , , , , , , ,

Jan 02

The Properties class has a store() method for saving a set of properties to a stream. There are lots of examples on the web that show how to use store() but unfortunately the majority of them fail to close the stream which is a bit misleading for new developers. Closing the stream is the responsibility of the caller (as mentioned in the javadoc), and failure to do it can result in the properties not being written to their ultimate destination.

Here’s an example showing how to write the properties to a file (including closing the stream).

Properties prop = new Properties();
OutputStream out = new FileOutputStream("my.properties"); 
try {
     prop.setProperty("abc", "123");
     prop.store(out, null);
} catch (IOException ex) {
     ex.printStackTrace();
} finally {
     out.close();
}

written by objects \\ tags: , , ,

Feb 01

The Java InputStream and OutputStream class are synchronized to be thread safe. If you are using them in a single thread application, or know that they will only be called by a single thread then this is an unnecessary overhead.

To remove the synchronization you can copy the source code from the Sun classes, rename the class, and remove the synchronization from all methods. You’ll then have an unsynchronized version of the stream class to use in your application.

written by objects \\ tags: , , ,