/** * Copyright (C) 2009-2013 FoundationDB, LLC * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.foundationdb.sql.ui; import javax.swing.*; import java.io.IOException; import java.io.OutputStream; public class TextAreaOutputStream extends OutputStream { private JTextArea textArea; private final StringBuilder buffer = new StringBuilder(); private final OutputStream oldStream; private int writeOldFrom; // Initialize in deferred mode. public TextAreaOutputStream() { this.oldStream = System.out; } public TextAreaOutputStream(JTextArea textArea) { this.textArea = textArea; this.oldStream = null; } public synchronized void write(int b) { buffer.append((char)b); } public synchronized void write(byte[] b) { buffer.append(new String(b)); } public synchronized void write(byte[] b, int off, int len) { buffer.append(new String(b, off, len)); } public synchronized void flush() throws IOException { final JTextArea textArea = this.textArea; if (textArea != null) { final String string = buffer.toString(); buffer.setLength(0); writeOldFrom = 0; SwingUtilities.invokeLater(new Runnable() { public void run() { textArea.append(string); } }); } else if (oldStream != null) { // Keep buffering in hopes that the console will appear, but still output // to stdout just in case. int end = buffer.length(); oldStream.write(buffer.subSequence(writeOldFrom, end).toString().getBytes()); writeOldFrom = end; } } // Change stream to outputting to text area. public synchronized boolean setTextAreaIfUnbound(JTextArea textArea) { if ((this.textArea == null) && (oldStream != null)) { this.textArea = textArea; return true; } return false; } // Change stream back to original output for any messages after frame is closed. public synchronized boolean clearTextAreaIfBound(JTextArea textArea) { if (this.textArea == textArea) { this.textArea = null; return true; } return false; } }