Mega Code Archive

 
Categories / Java / Development Class
 

Swing Console

/*  * IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved.  *   * http://izpack.org/  * http://izpack.codehaus.org/  *   * Copyright 2002 Jan Blok  *   * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  *   *     http://www.apache.org/licenses/LICENSE-2.0  *       * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License.  */ import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.text.Document; import javax.swing.text.Segment; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.io.*; import java.util.Vector; public final class Console {     public static final int INITIAL_WIDTH = 800;     public static final int INITIAL_HEIGHT = 600;     public static void main(String[] args)     {         Runtime rt = Runtime.getRuntime();         Process p = null;         try         {             /*              * Start a new process in which to execute the commands in cmd, using the environment in              * env and use pwd as the current working directory.              */             p = rt.exec(args);// , env, pwd);             new Console(p);             System.exit(p.exitValue());         }         catch (IOException e)         {             /*              * Couldn't even get the command to start. Most likely it couldn't be found because of a              * typo.              */             System.out.println("Error starting: " + args[0]);             System.out.println(e);         }     }     private StdOut so;     private StdOut se;     public String getOutputData()     {         if (so != null)         {             return so.getData();         }         else         {             return "";         }     }     public String getErrorData()     {         if (se != null)         {             return se.getData();         }         else         {             return "";         }     }     public Console(Process p)     {         JFrame frame = new JFrame();         frame.setTitle("Console");         Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();         frame.setLocation(screenSize.width / 2 - INITIAL_WIDTH / 2, screenSize.height / 2                 - INITIAL_HEIGHT / 2);         ConsoleTextArea cta = new ConsoleTextArea();         JScrollPane scroll = new JScrollPane(cta);         scroll.setPreferredSize(new Dimension(INITIAL_WIDTH, INITIAL_HEIGHT));         frame.getContentPane().add(scroll);         frame.pack();         // From here down your shell should be pretty much         // as it is written here!         /*          * Start up StdOut, StdIn and StdErr threads that write the output generated by the process          * p to the screen, and feed the keyboard input into p.          */         so = new StdOut(p, cta);         se = new StdOut(p, cta);         StdIn si = new StdIn(p, cta);         so.start();         se.start();         si.start();         // Wait for the process p to complete.         try         {             frame.setVisible(true);             p.waitFor();         }         catch (InterruptedException e)         {             /*              * Something bad happened while the command was executing.              */             System.out.println("Error during execution");             System.out.println(e);         }         /*          * Now signal the StdOut, StdErr and StdIn threads that the process is done, and wait for          * them to complete.          */         try         {             so.done();             se.done();             si.done();             so.join();             se.join();             si.join();         }         catch (InterruptedException e)         {             // Something bad happend to one of the Std threads.             System.out.println("Error in StdOut, StdErr or StdIn.");             System.out.println(e);         }         frame.setVisible(false);     } } class StdIn extends Thread {     private BufferedReader kb;     private boolean processRunning;     private PrintWriter op;     public StdIn(Process p, ConsoleTextArea cta)     {         setDaemon(true);         InputStreamReader ir = new InputStreamReader(cta.getIn());         kb = new BufferedReader(ir);         BufferedOutputStream os = new BufferedOutputStream(p.getOutputStream());         op = new PrintWriter((new OutputStreamWriter(os)), true);         processRunning = true;     }     public void run()     {         try         {             while (kb.ready() || processRunning)             {                 if (kb.ready())                 {                     op.println(kb.readLine());                 }             }         }         catch (IOException e)         {             System.err.println("Problem reading standard input.");             System.err.println(e);         }     }     public void done()     {         processRunning = false;     } } class StdOut extends Thread {     private InputStreamReader output;     private boolean processRunning;     private ConsoleTextArea cta;     private StringBuffer data;     public StdOut(Process p, ConsoleTextArea cta)     {         setDaemon(true);         output = new InputStreamReader(p.getInputStream());         this.cta = cta;         processRunning = true;         data = new StringBuffer();     }     public void run()     {         try         {             /*              * Loop as long as there is output from the process to be displayed or as long as the              * process is still running even if there is presently no output.              */             while (output.ready() || processRunning)             {                 // If there is output get it and display it.                 if (output.ready())                 {                     char[] array = new char[255];                     int num = output.read(array);                     if (num != -1)                     {                         String s = new String(array, 0, num);                         data.append(s);                         SwingUtilities.invokeAndWait(new ConsoleWrite(cta, s));                     }                 }             }         }         catch (Exception e)         {             System.err.println("Problem writing to standard output.");             System.err.println(e);         }     }     public void done()     {         processRunning = false;     }     public String getData()     {         return data.toString();     } } class ConsoleWrite implements Runnable {     private ConsoleTextArea textArea;     private String str;     public ConsoleWrite(ConsoleTextArea textArea, String str)     {         this.textArea = textArea;         this.str = str;     }     public void run()     {         textArea.write(str);     } } class ConsoleWriter extends java.io.OutputStream {     private ConsoleTextArea textArea;     private StringBuffer buffer;     public ConsoleWriter(ConsoleTextArea textArea)     {         this.textArea = textArea;         buffer = new StringBuffer();     }     public synchronized void write(int ch)     {         buffer.append((char) ch);         if (ch == '\n')         {             flushBuffer();         }     }     public synchronized void write(char[] data, int off, int len)     {         for (int i = off; i < len; i++)         {             buffer.append(data[i]);             if (data[i] == '\n')             {                 flushBuffer();             }         }     }     public synchronized void flush()     {         if (buffer.length() > 0)         {             flushBuffer();         }     }     public void close()     {         flush();     }     private void flushBuffer()     {         String str = buffer.toString();         buffer.setLength(0);         SwingUtilities.invokeLater(new ConsoleWrite(textArea, str));     } } class ConsoleTextArea extends JTextArea implements KeyListener, DocumentListener {     /**      *      */     private static final long serialVersionUID = 3258410625414475827L;     private ConsoleWriter console1;     private PrintStream out;     private PrintStream err;     private PrintWriter inPipe;     private PipedInputStream in;     private Vector<String> history;     private int historyIndex = -1;     private int outputMark = 0;     public void select(int start, int end)     {         requestFocus();         super.select(start, end);     }     public ConsoleTextArea()     {         super();         history = new java.util.Vector<String>();         console1 = new ConsoleWriter(this);         ConsoleWriter console2 = new ConsoleWriter(this);         out = new PrintStream(console1);         err = new PrintStream(console2);         PipedOutputStream outPipe = new PipedOutputStream();         inPipe = new PrintWriter(outPipe);         in = new PipedInputStream();         try         {             outPipe.connect(in);         }         catch (IOException exc)         {             exc.printStackTrace();         }         getDocument().addDocumentListener(this);         addKeyListener(this);         setLineWrap(true);         setFont(new Font("Monospaced", 0, 12));     }     void returnPressed()     {         Document doc = getDocument();         int len = doc.getLength();         Segment segment = new Segment();         try         {             synchronized (doc)             {                 doc.getText(outputMark, len - outputMark, segment);             }         }         catch (javax.swing.text.BadLocationException ignored)         {             ignored.printStackTrace();         }         if (segment.count > 0)         {             history.addElement(segment.toString());         }         historyIndex = history.size();         inPipe.write(segment.array, segment.offset, segment.count);         append("\n");         synchronized (doc)         {             outputMark = doc.getLength();         }         inPipe.write("\n");         inPipe.flush();         console1.flush();     }     public void eval(String str)     {         inPipe.write(str);         inPipe.write("\n");         inPipe.flush();         console1.flush();     }     public void keyPressed(KeyEvent e)     {         int code = e.getKeyCode();         if (code == KeyEvent.VK_BACK_SPACE || code == KeyEvent.VK_LEFT)         {             if (outputMark == getCaretPosition())             {                 e.consume();             }         }         else if (code == KeyEvent.VK_HOME)         {             int caretPos = getCaretPosition();             if (caretPos == outputMark)             {                 e.consume();             }             else if (caretPos > outputMark)             {                 if (!e.isControlDown())                 {                     if (e.isShiftDown())                     {                         moveCaretPosition(outputMark);                     }                     else                     {                         setCaretPosition(outputMark);                     }                     e.consume();                 }             }         }         else if (code == KeyEvent.VK_ENTER)         {             returnPressed();             e.consume();         }         else if (code == KeyEvent.VK_UP)         {             historyIndex--;             if (historyIndex >= 0)             {                 if (historyIndex >= history.size())                 {                     historyIndex = history.size() - 1;                 }                 if (historyIndex >= 0)                 {                     String str = history.elementAt(historyIndex);                     int len = getDocument().getLength();                     replaceRange(str, outputMark, len);                     int caretPos = outputMark + str.length();                     select(caretPos, caretPos);                 }                 else                 {                     historyIndex++;                 }             }             else             {                 historyIndex++;             }             e.consume();         }         else if (code == KeyEvent.VK_DOWN)         {             int caretPos = outputMark;             if (history.size() > 0)             {                 historyIndex++;                 if (historyIndex < 0)                 {                     historyIndex = 0;                 }                 int len = getDocument().getLength();                 if (historyIndex < history.size())                 {                     String str = history.elementAt(historyIndex);                     replaceRange(str, outputMark, len);                     caretPos = outputMark + str.length();                 }                 else                 {                     historyIndex = history.size();                     replaceRange("", outputMark, len);                 }             }             select(caretPos, caretPos);             e.consume();         }     }     public void keyTyped(KeyEvent e)     {         int keyChar = e.getKeyChar();         if (keyChar == 0x8 /* KeyEvent.VK_BACK_SPACE */)         {             if (outputMark == getCaretPosition())             {                 e.consume();             }         }         else if (getCaretPosition() < outputMark)         {             setCaretPosition(outputMark);         }     }     public void keyReleased(KeyEvent e)     {     }     public synchronized void write(String str)     {         insert(str, outputMark);         int len = str.length();         outputMark += len;         select(outputMark, outputMark);     }     public synchronized void insertUpdate(DocumentEvent e)     {         int len = e.getLength();         int off = e.getOffset();         if (outputMark > off)         {             outputMark += len;         }     }     public synchronized void removeUpdate(DocumentEvent e)     {         int len = e.getLength();         int off = e.getOffset();         if (outputMark > off)         {             if (outputMark >= off + len)             {                 outputMark -= len;             }             else             {                 outputMark = off;             }         }     }     public void postUpdateUI()     {         // this attempts to cleanup the damage done by updateComponentTreeUI         requestFocus();         setCaret(getCaret());         synchronized (this)         {             select(outputMark, outputMark);         }     }     public void changedUpdate(DocumentEvent e)     {     }     public InputStream getIn()     {         return in;     }     public PrintStream getOut()     {         return out;     }     public PrintStream getErr()     {         return err;     } }