package edu.cmu.minorthird.util.gui; import java.awt.Font; import java.io.IOException; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.io.PrintStream; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JScrollBar; import javax.swing.JScrollPane; import javax.swing.JTextArea; /** Implements the console window for the gui * * @author Cameron Williams */ public class Console{ private PipedInputStream piOut; private PipedOutputStream poOut; // private final PipedInputStream piErr = new PipedInputStream(); private JTextArea errorArea; private JScrollPane scroller; private Thread mainThread,readerThread; private boolean doMainRunning; private PrintStream oldSystemOut; private JButton viewButton; // private Object ui; private Object task; // private boolean labels; public Console(Console.Task t){ this.errorArea=new JTextArea(20,100); errorArea.setFont(new Font("monospaced",Font.PLAIN,12)); scroller=new JScrollPane(errorArea); this.task=t; } /** Constructor initializes the task, whether labels are present, and the viewButton */ public Console(Object t,boolean l,JButton vb){ this.errorArea=new JTextArea(20,100); errorArea.setFont(new Font("monospaced",Font.PLAIN,12)); scroller=new JScrollPane(errorArea); this.task=t; this.viewButton=vb; // this.labels=l; } /** The outermost component of the console. */ public JComponent getMainComponent(){ return scroller; } /** Start the task for the console. */ public void start(){ initThreads(); try{ oldSystemOut=System.out; piOut=new PipedInputStream(); poOut=new PipedOutputStream(piOut); System.setOut(new PrintStream(poOut,true)); }catch(java.io.IOException io){ errorArea.append("Couldn't redirect output\n"+io.getMessage()+"\n"); }catch(SecurityException se){ errorArea.append("SE error"+se.getMessage()+"\n"); } mainThread.start(); } /** Append a string to the console window. */ public void append(String s){ errorArea.append(s); scrollDown(); } /** Clear the console window. */ public void clear(){ errorArea.setText(""); } /** Re-initialize the threads for the console */ private void initThreads(){ // mainthread - runs the main task with doMain mainThread=new Thread(){ @Override public void run(){ if(task instanceof Console.Task){ viewButton.setEnabled(false); if(!((Console.Task)task).getLabels()){ errorArea .append("\nYou need to specify the labeled data you're using!\n" +"Modify the 'labels' parameters under base parameters section\n" +"of the parameter modification window.\n"); }else{ long startTime=System.currentTimeMillis(); doMainRunning=true; readerThread.start(); ((Console.Task)task).doMain(); double elapsedTime=(System.currentTimeMillis()-startTime)/1000.0; System.out.println("\nTotal time for task: "+elapsedTime+" sec"); viewButton.setEnabled(((Console.Task)task).getMainResult()!=null); doMainRunning=false; // signal reader to stop try{ readerThread.join(); // wait for it to end }catch(InterruptedException ex){ System.err.println("reader interrupted?"); } scrollDown(); } }else{ errorArea.append("Error: Task is not an instance of Console.Task \n"); }//end else } //end run }; // end thread // this thread traps output from mainThread and sticks it in // console window readerThread=new Thread(){ @Override public void run(){ try{ byte[] buf=new byte[2048]; int len=0; while(doMainRunning){ // look for more output if((len=piOut.read(buf))>0){ errorArea.append(new String(buf,0,len)); scrollDown(); } yield(); // let someone else in to execute } // clean up any output we might have missed // after exiting if((len=piOut.read(buf))>0){ errorArea.append(new String(buf,0,len)); scrollDown(); } closePipes(); }catch(IOException e){ errorArea.append(e.getMessage()); System.out.println(e.getMessage()); } } }; //end reader Thread } // constructor // imperfect method to scroll to bottom private void scrollDown(){ try{ JScrollBar bar=scroller.getVerticalScrollBar(); bar.setValue(bar.getMaximum()); }catch(Exception ex){ System.err.println("error scrolling: "+ex); } } private void closePipes(){ try{ poOut.close(); piOut.close(); System.setOut(oldSystemOut); }catch(Exception e){ System.out.println(e.getMessage()); } } /** Interface for objects that can be configured with command-line arguments. * Configuration for x is done by calling <code>x.doMain().</code> */ public interface Task{ public boolean getLabels(); public void doMain(); public Object getMainResult(); } }