/* * Copyright (C) 2004 The Concord Consortium, Inc., * 10 Concord Crossing, Concord, MA 01742 * * Web Site: http://www.concord.org * Email: info@concord.org * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * END LICENSE */ package org.concord.swing; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; import java.util.Vector; import javax.swing.JFrame; import javax.swing.JTextArea; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; public class Console extends JTextArea { protected static final WindowAdapter closer = new WindowAdapter() { public void windowClosing(WindowEvent event) { JFrame frame = (JFrame) event.getSource(); frame.dispose(); } }; boolean running = false; protected Vector listeners = new Vector(); protected Vector streamThreads = new Vector(); protected Process process; protected Thread outputProcess; protected Thread errorProcess; protected Thread monitorProcess; public Console() { this(null); } public Console(Process process) { setProcess(process); } public void setProcess(Process newProcess) { if (process instanceof Process) { process.destroy(); try { process.waitFor(); } catch (InterruptedException e) { } } process = newProcess; if (process == null) return; setText(""); streamThreads.removeAllElements(); addInputStream(process.getInputStream(), "stdout"); addInputStream(process.getErrorStream(), "stderr"); monitorProcess = new Thread() { public void run() { try { if (process instanceof Process) process.waitFor(); running = false; process = null; if (listeners.size() > 0) { ChangeEvent changeEvent = new ChangeEvent(Console.this); for (int i = 0; i < listeners.size(); i++) { ChangeListener listener = (ChangeListener) listeners.elementAt(i); listener.stateChanged(changeEvent); } } } catch (InterruptedException e) { } } }; start(); monitorProcess.setPriority(Thread.MIN_PRIORITY); monitorProcess.start(); } public void start() { running = true; for(int i=0; i< streamThreads.size(); i++) { Thread thread = (Thread)streamThreads.elementAt(i); thread.start(); } } public void addInputStream(InputStream stream, String name) { Thread thread = new StreamThread(stream, name); streamThreads.addElement(thread); } class StreamThread extends Thread { InputStream stream; String name; StreamThread(InputStream stream, String name) { super(name); this.stream = stream; this.name = name; } public void run() { byte [] buffer = new byte[1024]; while (running) { try { for (int n = stream.read(buffer); n > 0; n = stream.read(buffer)) { String strDebug = new String(buffer, 0, n); if(System.getProperty("os.name").equals("Mac OS")){ strDebug = strDebug.replace('\r','\n'); } Console.this.append(strDebug); } } catch (Exception e) { Console.this.append(e.toString()); } } } } public PrintStream getPrintStream() { return new PrintStream(new ConsoleOutputStream(), true); } class ConsoleOutputStream extends OutputStream { byte[] bytes = new byte [1]; public void write(int b) { bytes[0] = (byte)b; append(new String(bytes)); } public void write(byte[] b) { append(new String(b)); } public void write(byte[] b, int off, int len) { append(new String(b, off, len)); } } public Process getProcess() { return process; } public void addChangeListener(ChangeListener listener) { listeners.addElement(listener); } public void removeChangeListener(ChangeListener listener) { listeners.removeElement(listener); } }