package jas2.swingstudio;

import java.io.*;
import javax.swing.*;
import javax.swing.text.*;

/**
 * A Writer implementation that places it's
 * output in a swing text model (Document).  The 
 * Document can be either a plain text or styled
 * document implementation.  If styled, the attributes
 * assigned to the output stream will be used in
 * the display of the output.
 *
 * Based on:
 * http://java.sun.com/products/jfc/tsc/text/console/DocumentWriter.java
 * @author  Timothy Prinzing
 * @version 1.1 02/05/99
 */
public class JASConsoleDocumentWriter extends Writer {
	/**
	 * Constructs an output stream that will output to the
	 * given document with the given set of character attributes.
	 *
	 * @param doc the document to write to.
	 * @param a the character attributes to use for the written text.
	 */
	public JASConsoleDocumentWriter(Document doc, AttributeSet a,
									String s, JASConsoleTabbedPane j) {
        theDocument = doc;
        theAttributeSet = a;
		theScrollPaneName = s;
		theTabbedPane = j;
    }
	/**
	 * Write a portion of an array of characters.
	 *
	 * @param  cbuf  Array of characters
	 * @param  off   Offset from which to start writing characters
	 * @param  len   Number of characters to write
	 *
	 * @exception  IOException  If an I/O error occurs
	 */
	public void write(char cbuf[], int off, int len) throws IOException {
		write(new String(cbuf, off, len));
	}
	/**
	 * Write a portion of a string.
	 *
	 * @param  str  A String
	 * @param  off  Offset from which to start writing characters
	 * @param  len  Number of characters to write
	 *
	 * @exception  IOException  If an I/O error occurs
	 */
	public void write(String str, int off, int len) throws IOException {
		write(str.substring(off, len));
	}
	/**
	 * Write a string.
	 *
	 * @param  str  String to be written
	 *
	 * @exception  IOException  If an I/O error occurs
	 */
	public void write(String str) throws IOException {
		if (theDocument == null) {
			throw new IOException("Writer was closed");
		}
        try {
			int theTabIndex = theTabbedPane.indexOfTab(theScrollPaneName);
			//I still have to use the tab index to check if the tab
			//with a given name is in theTabbedPane--the difference is now
			//I look up the index instead of stupidly storing it!
			if (theTabIndex != -1) {
				theTabbedPane.setSelectedIndex(theTabIndex);
			} else {
				//make a new JASConsoleScrollPane
				JASConsoleScrollPane theScrollPane =
					theTabbedPane.getSelectedConsoleScrollPane();

				//now make a new scroll pane, add it to the tabbed pane and set selected
				JASConsoleScrollPane theNewScrollPane =
					new JASConsoleScrollPane(theScrollPaneName, theTabbedPane);
				theTabbedPane.addTab(theScrollPaneName,theNewScrollPane);
				theTabIndex = theTabbedPane.indexOfTab(theScrollPaneName);
				theTabbedPane.setSelectedIndex(theTabIndex);
				
				//the JASConsoleScrollPane constructor inits the JASConsoleTextPane
				//so now I can set the Document!
				theNewScrollPane.getTheTextArea().setDocument(theDocument);
				theNewScrollPane.setOutputAttributes(theAttributeSet);
			}
			//now that we're here, the correct scroll pane exist and be focused
			//so write the string
            theDocument.insertString(theDocument.getLength(), str, theAttributeSet);
			//and optionally append it to the log file also
			appendToLog(str);
			//and make sure that our Document hasn't gotten too big
			JASConsoleDocumentUtilities.trimDoc(theDocument);
			theTabbedPane.getSelectedConsoleScrollPane().scrollToEnd();
        } catch (BadLocationException ble) {
            throw new IOException(ble.getMessage());
		}
	}
	/**
	 * Flush the stream.  If the stream has saved any characters from the
	 * various write() methods in a buffer, write them immediately to their
	 * intended destination.  Then, if that destination is another character or
	 * byte stream, flush it.  Thus one flush() invocation will flush all the
	 * buffers in a chain of Writers and OutputStreams.
	 *
	 * @exception  IOException  If an I/O error occurs
	 */
	public void flush() throws IOException {
		if (theDocument == null) {
			throw new IOException("Writer was closed");
		}
		// nothing to do, everything is immediately placed into the
		// document model.
	}

	/**
	 * Close the stream, flushing it first.  Once a stream has been closed,
	 * further write() or flush() invocations will cause an IOException to be
	 * thrown.  Closing a previously-closed stream, however, has no effect.
	 *
	 * @exception  IOException  If an I/O error occurs
	 */
	public void close() throws IOException {
		theDocument = null;
	}
	
	private void appendToLog(String s) {
		JASConsoleScrollPane theScrollPane = theTabbedPane.getSelectedConsoleScrollPane();
		//WORKAROUND!
		if (theScrollPane != null && ((JASConsoleTextArea)theScrollPane.getTheTextArea()).isLoggingOn()) {
			try {
				((JASConsoleTextArea)theScrollPane.getTheTextArea()).getLogWriter().write(s);
				((JASConsoleTextArea)theScrollPane.getTheTextArea()).getLogWriter().flush();
			} catch (IOException eek) {
			}
		}
	}
	
	private String theScrollPaneName;
    private Document theDocument;
	private AttributeSet theAttributeSet;
	private JASConsoleTabbedPane theTabbedPane;
}

 

Ads help maintain this website.