[an error occurred while processing this directive]

Page One
Page Two
The Databank
What Is Swing?
Special Report
IDE Roundup
Swing and the Web
Swing Text
Tech Topics
Friends
Tips and Tricks
The PLAF Papers
Call 911
The Archive
JFC Home
Download Swing
Swing API Docs
Download JDK
JDK Docs
Java Tutorial
 
The Swing Connection Swing Text

A Console for Output Streams

By Timothy Prinzing

The JavaTM programming language's I/O package provides a large collection of classes that support different kinds of input/output streams, such as streams that are bound to files, buffered streams, and streams that support special operations like simple parsing. Most commonly, these classes are used for reading and writing files, and for reading and writing the user's console terminal.

The console terminal is usually the display window associated with a Java programming language process. For instance, if the user starts a Java application from a UNIX shell window, that window becomes the console.

Sometimes the console isn't nearly so convenient. When an applet is run in a browser such as Netscape Navigator, for example, the console is a special write-only window that isn't shown by default.

In this article, we'll explain how to write a new Swing class, called "ConsolePane," that displays one or more output streams. The ConsolePane class can be used to create a component, much like a UNIX or MS-DOS shell window, that can parse commands typed in by a user and can display the output generated by the subprocesses carrying out those commands.

The ConsolePane Class

At the end of the article, there's source code for an example program named CommandConsole. When you run the program, it displays a console window that looks like this:

 

In the next section, we'll show how to connect streams to Swing text components. Then, in the section titled "Displaying Output from a Process," we'll show how to define the ConsolePane class.


Connecting an OutputStream to a Swing Document

The Swing text components delegate the responsibility for managing the text they display to a separate model called a Document. Swing provides Document classes for strings and for HTML and RTF files. To create a Document that displays an output stream, we'll define a new OutputStream class that contains a Document:

public class DocumentOutputStream extends OutputStream {
    private Document doc;

    public DocumentOutputStream(Document doc) {
	this.doc = doc;
    }

    public void write(int b) throws IOException {
	write(new Byte[]{b}, 0, 1);
    }

    public void write(byte b[], int off, int len) throws IOException {
	try {
	    doc.insertString(doc.getLength(), 
                        new String(b, off, len), null);
	} 
	catch (BadLocationException ble) {
	    throw new IOException(ble.getMessage());
	}
    }
}

All the OutputStream methods eventually just call the three-argument write() method -- and we've overridden that to call Document.insertString() in a way that just appends the incoming text to the end of the Document.

The Java I/O package includes another class like OutputStream called Writer. Both Reader and Writer were introduced in the 1.1 release of Java to address some shortcomings in the corresponding Stream base classes. The implementation of DocumentWriter class is very similar to DocumentOutputStream.

Here's a simple example that displays a DocumentOutputStream in a Swing TextPane (the HelloWorld.java and DocumentOutputStream.java files contain the complete source code for this example):

JTextArea textArea = new JTextArea();
Document doc = textArea.getDocument();
PrintStream out = new PrintStream(new DocumentOutputStream(doc));
out.println("Hello World");
    

Displaying Output from a Process

The Java Runtime class can be used to create a new native subprocess that will execute asynchronously. Each process object has two output streams: one for ordinary output and one for errors. The ConsolePane class creates threads that read these streams, one line at a time, and then copies the lines to a PrintStream that's connected to a DocumentOutputStream as in the previous section. The Swing Document classes are thread-safe, so many subprocesses can safely write to the console.

The workhorse of the ConsolePane class is the showProcessOutput() method. It starts the threads to read a processes normal and error output streams an then connects them to the Document that displays all output. An example application, called CommandConsole, adds a text field for the user to enter commands and creates subprocesses for each line entered. To the right of the text field, there's a button that stops the current process.

Here are the source files for the CommandConsole application:

The console_examples.zip file contains all these source files, plus object code and resources.

 


WARNING: To compile and run the CommandConsole program, you'll need the most recent version of Swing because it fixes a number of bugs related to concurrency. More specifically, you'll need Swing Version 1.1.1 beta 1 or JDK Version 1.2.1. (The latter was not available when this article went online, but should be available soon.)

 

[an error occurred while processing this directive]