001: package kawa;
002:
003: import java.io.*;
004: import java.awt.*;
005: import java.awt.event.*;
006:
007: /** Simple TextArea that always scrolls to the bottom. Also creates an
008: * out and err PrintWriter so that you can redirect stdout/stderr to
009: * these streams, using the System.setOut/setErr methods.
010: *
011: * @author Albert Ting
012: */
013: public class MessageArea extends TextArea implements KeyListener,
014: TextListener {
015: private kawa.TextAreaWriter out_stream;
016: private PrintWriter out;
017: private PrintWriter err;
018: gnu.text.QueueReader in;
019:
020: public int outputMark = 0;
021: public int endMark = -1;
022: int length = 0;
023:
024: /**
025: * simple TextArea that always scrolls to the bottom. Also creates an
026: * out and err PrintWriter so that you can redirect stdout/stderr to
027: * these streams, using the System.setOut/setErr methods.
028: */
029: public MessageArea(gnu.text.QueueReader in) {
030: super ();
031:
032: this .in = in;
033:
034: out_stream = new kawa.TextAreaWriter(this );
035: kawa.TextAreaWriter err_stream = new kawa.TextAreaWriter(this );
036: out = new PrintWriter(out_stream);
037: err = new PrintWriter(err_stream);
038:
039: addKeyListener(this );
040: addTextListener(this );
041: }
042:
043: void enter() {
044: int pos = getCaretPosition();
045: String str = getText();
046: int len = str.length();
047: if (len != length) {
048: System.err.println("(actual) len:" + len
049: + " (saved) length:" + length);
050: }
051: int lineAfter = str.indexOf('\n', pos);
052: endMark = -1;
053: if (lineAfter < 0)
054: lineAfter = len;
055: int lineBefore = pos == 0 ? 0 : 1 + str.lastIndexOf('\n',
056: pos - 1);
057: if (pos >= outputMark || outputMark <= lineAfter) {
058: lineAfter = str.indexOf('\n', outputMark);
059: if (lineAfter < 0) {
060: lineAfter = len;
061: append("\n");
062: } else
063: endMark = len;
064: str = str.substring(outputMark, lineAfter);
065: str = str + '\n';
066: outputMark = lineAfter + 1;
067: } else {
068: str = str.substring(lineBefore, lineAfter + 1);
069: out_stream.write(str);
070: }
071:
072: setCaretPosition(outputMark);
073:
074: if (in != null) {
075: in.append(str);
076: }
077: }
078:
079: public void keyPressed(KeyEvent e) {
080: int code = e.getKeyCode();
081: if (code == KeyEvent.VK_ENTER) {
082: enter();
083: e.consume();
084: }
085: }
086:
087: public void keyReleased(KeyEvent e) {
088: }
089:
090: public void keyTyped(KeyEvent e) {
091: }
092:
093: public synchronized void write(String str) {
094: boolean moveCaret = getCaretPosition() == outputMark;
095: insert(str, outputMark);
096: int len = str.length();
097: outputMark += len;
098: if (moveCaret)
099: setCaretPosition(outputMark);
100: if (endMark >= 0)
101: endMark += len;
102: }
103:
104: /** Delete old text, prior to line containing outputMark. */
105:
106: public synchronized void deleteOldText() {
107: String str = getText();
108: int lineBefore = (outputMark <= 0 ? 0 : (str.lastIndexOf('\n',
109: outputMark - 1)) + 1);
110: setCaretPosition(outputMark);
111: replaceRange("", 0, lineBefore);
112: }
113:
114: public synchronized void textValueChanged(TextEvent e) {
115: int pos = getCaretPosition();
116: String text = getText();
117: int delta = text.length() - length;
118: length += delta;
119: if (pos < outputMark)
120: outputMark += delta;
121: else if (pos - delta < outputMark)
122: outputMark = pos;
123: if (endMark >= 0) {
124: if (pos < endMark)
125: endMark += delta;
126: else if (pos - delta < endMark)
127: endMark = pos;
128: }
129: }
130:
131: public PrintWriter getStdout() {
132: return out;
133: }
134:
135: public PrintWriter getStderr() {
136: return err;
137: }
138:
139: }
|