KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > izforge > izpack > util > Console


1 /*
2  * IzPack - Copyright 2001-2007 Julien Ponge, All Rights Reserved.
3  *
4  * http://www.izforge.com/izpack/
5  * http://developer.berlios.de/projects/izpack/
6  *
7  * Copyright 2002 Jan Blok
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */

21
22 package com.izforge.izpack.util;
23
24 import java.awt.Dimension JavaDoc;
25 import java.awt.Font JavaDoc;
26 import java.awt.Toolkit JavaDoc;
27 import java.awt.event.KeyEvent JavaDoc;
28 import java.awt.event.KeyListener JavaDoc;
29 import java.io.BufferedOutputStream JavaDoc;
30 import java.io.BufferedReader JavaDoc;
31 import java.io.IOException JavaDoc;
32 import java.io.InputStream JavaDoc;
33 import java.io.InputStreamReader JavaDoc;
34 import java.io.OutputStreamWriter JavaDoc;
35 import java.io.PipedInputStream JavaDoc;
36 import java.io.PipedOutputStream JavaDoc;
37 import java.io.PrintStream JavaDoc;
38 import java.io.PrintWriter JavaDoc;
39
40 import javax.swing.JFrame JavaDoc;
41 import javax.swing.JScrollPane JavaDoc;
42 import javax.swing.JTextArea JavaDoc;
43 import javax.swing.SwingUtilities JavaDoc;
44 import javax.swing.event.DocumentEvent JavaDoc;
45 import javax.swing.event.DocumentListener JavaDoc;
46 import javax.swing.text.Document JavaDoc;
47 import javax.swing.text.Segment JavaDoc;
48
49 public final class Console
50 {
51
52     public static final int INITIAL_WIDTH = 800;
53
54     public static final int INITIAL_HEIGHT = 600;
55
56     public static void main(String JavaDoc[] args)
57     {
58         Runtime JavaDoc rt = Runtime.getRuntime();
59         Process JavaDoc p = null;
60         try
61         {
62
63             /*
64              * Start a new process in which to execute the commands in cmd, using the environment in
65              * env and use pwd as the current working directory.
66              */

67             p = rt.exec(args);// , env, pwd);
68
new Console(p);
69             System.exit(p.exitValue());
70         }
71         catch (IOException JavaDoc e)
72         {
73             /*
74              * Couldn't even get the command to start. Most likely it couldn't be found because of a
75              * typo.
76              */

77             System.out.println("Error starting: " + args[0]);
78             System.out.println(e);
79         }
80     }
81
82     private StdOut so;
83
84     private StdOut se;
85
86     public String JavaDoc getOutputData()
87     {
88         if (so != null)
89         {
90             return so.getData();
91         }
92         else
93         {
94             return "";
95         }
96     }
97
98     public String JavaDoc getErrorData()
99     {
100         if (se != null)
101         {
102             return se.getData();
103         }
104         else
105         {
106             return "";
107         }
108     }
109
110     public Console(Process JavaDoc p)
111     {
112         JFrame JavaDoc frame = new JFrame JavaDoc();
113         frame.setTitle("Console");
114         Dimension JavaDoc screenSize = Toolkit.getDefaultToolkit().getScreenSize();
115         frame.setLocation(screenSize.width / 2 - INITIAL_WIDTH / 2, screenSize.height / 2
116                 - INITIAL_HEIGHT / 2);
117         ConsoleTextArea cta = new ConsoleTextArea();
118         JScrollPane JavaDoc scroll = new JScrollPane JavaDoc(cta);
119         scroll.setPreferredSize(new Dimension JavaDoc(INITIAL_WIDTH, INITIAL_HEIGHT));
120         frame.getContentPane().add(scroll);
121         frame.pack();
122
123         // From here down your shell should be pretty much
124
// as it is written here!
125
/*
126          * Start up StdOut, StdIn and StdErr threads that write the output generated by the process
127          * p to the screen, and feed the keyboard input into p.
128          */

129         so = new StdOut(p, cta);
130         se = new StdOut(p, cta);
131         StdIn si = new StdIn(p, cta);
132         so.start();
133         se.start();
134         si.start();
135
136         // Wait for the process p to complete.
137
try
138         {
139             frame.setVisible(true);
140             p.waitFor();
141         }
142         catch (InterruptedException JavaDoc e)
143         {
144             /*
145              * Something bad happened while the command was executing.
146              */

147             System.out.println("Error during execution");
148             System.out.println(e);
149         }
150
151         /*
152          * Now signal the StdOut, StdErr and StdIn threads that the process is done, and wait for
153          * them to complete.
154          */

155         try
156         {
157             so.done();
158             se.done();
159             si.done();
160             so.join();
161             se.join();
162             si.join();
163         }
164         catch (InterruptedException JavaDoc e)
165         {
166             // Something bad happend to one of the Std threads.
167
System.out.println("Error in StdOut, StdErr or StdIn.");
168             System.out.println(e);
169         }
170         frame.setVisible(false);
171     }
172 }
173
174 class StdIn extends Thread JavaDoc
175 {
176
177     private BufferedReader JavaDoc kb;
178
179     private boolean processRunning;
180
181     private PrintWriter JavaDoc op;
182
183     public StdIn(Process JavaDoc p, ConsoleTextArea cta)
184     {
185         setDaemon(true);
186         InputStreamReader JavaDoc ir = new InputStreamReader JavaDoc(cta.getIn());
187         kb = new BufferedReader JavaDoc(ir);
188
189         BufferedOutputStream JavaDoc os = new BufferedOutputStream JavaDoc(p.getOutputStream());
190         op = new PrintWriter JavaDoc((new OutputStreamWriter JavaDoc(os)), true);
191         processRunning = true;
192     }
193
194     public void run()
195     {
196         try
197         {
198             while (kb.ready() || processRunning)
199             {
200                 if (kb.ready())
201                 {
202                     op.println(kb.readLine());
203                 }
204             }
205         }
206         catch (IOException JavaDoc e)
207         {
208             System.err.println("Problem reading standard input.");
209             System.err.println(e);
210         }
211     }
212
213     public void done()
214     {
215         processRunning = false;
216     }
217 }
218
219 class StdOut extends Thread JavaDoc
220 {
221
222     private InputStreamReader JavaDoc output;
223
224     private boolean processRunning;
225
226     private ConsoleTextArea cta;
227
228     private StringBuffer JavaDoc data;
229
230     public StdOut(Process JavaDoc p, ConsoleTextArea cta)
231     {
232         setDaemon(true);
233         output = new InputStreamReader JavaDoc(p.getInputStream());
234         this.cta = cta;
235         processRunning = true;
236         data = new StringBuffer JavaDoc();
237     }
238
239     public void run()
240     {
241         try
242         {
243             /*
244              * Loop as long as there is output from the process to be displayed or as long as the
245              * process is still running even if there is presently no output.
246              */

247             while (output.ready() || processRunning)
248             {
249
250                 // If there is output get it and display it.
251
if (output.ready())
252                 {
253                     char[] array = new char[255];
254                     int num = output.read(array);
255                     if (num != -1)
256                     {
257                         String JavaDoc s = new String JavaDoc(array, 0, num);
258                         data.append(s);
259                         SwingUtilities.invokeAndWait(new ConsoleWrite(cta, s));
260                     }
261                 }
262             }
263         }
264         catch (Exception JavaDoc e)
265         {
266             System.err.println("Problem writing to standard output.");
267             System.err.println(e);
268         }
269     }
270
271     public void done()
272     {
273         processRunning = false;
274     }
275
276     public String JavaDoc getData()
277     {
278         return data.toString();
279     }
280 }
281
282 class ConsoleWrite implements Runnable JavaDoc
283 {
284
285     private ConsoleTextArea textArea;
286
287     private String JavaDoc str;
288
289     public ConsoleWrite(ConsoleTextArea textArea, String JavaDoc str)
290     {
291         this.textArea = textArea;
292         this.str = str;
293     }
294
295     public void run()
296     {
297         textArea.write(str);
298     }
299 }
300
301 class ConsoleWriter extends java.io.OutputStream JavaDoc
302 {
303
304     private ConsoleTextArea textArea;
305
306     private StringBuffer JavaDoc buffer;
307
308     public ConsoleWriter(ConsoleTextArea textArea)
309     {
310         this.textArea = textArea;
311         buffer = new StringBuffer JavaDoc();
312     }
313
314     public synchronized void write(int ch)
315     {
316         buffer.append((char) ch);
317         if (ch == '\n')
318         {
319             flushBuffer();
320         }
321     }
322
323     public synchronized void write(char[] data, int off, int len)
324     {
325         for (int i = off; i < len; i++)
326         {
327             buffer.append(data[i]);
328             if (data[i] == '\n')
329             {
330                 flushBuffer();
331             }
332         }
333     }
334
335     public synchronized void flush()
336     {
337         if (buffer.length() > 0)
338         {
339             flushBuffer();
340         }
341     }
342
343     public void close()
344     {
345         flush();
346     }
347
348     private void flushBuffer()
349     {
350         String JavaDoc str = buffer.toString();
351         buffer.setLength(0);
352         SwingUtilities.invokeLater(new ConsoleWrite(textArea, str));
353     }
354 }
355
356 class ConsoleTextArea extends JTextArea JavaDoc implements KeyListener JavaDoc, DocumentListener JavaDoc
357 {
358
359     /**
360      *
361      */

362     private static final long serialVersionUID = 3258410625414475827L;
363
364     private ConsoleWriter console1;
365
366     private PrintStream JavaDoc out;
367
368     private PrintStream JavaDoc err;
369
370     private PrintWriter JavaDoc inPipe;
371
372     private PipedInputStream JavaDoc in;
373
374     private java.util.Vector JavaDoc history;
375
376     private int historyIndex = -1;
377
378     private int outputMark = 0;
379
380     public void select(int start, int end)
381     {
382         requestFocus();
383         super.select(start, end);
384     }
385
386     public ConsoleTextArea()
387     {
388         super();
389         history = new java.util.Vector JavaDoc();
390         console1 = new ConsoleWriter(this);
391         ConsoleWriter console2 = new ConsoleWriter(this);
392         out = new PrintStream JavaDoc(console1);
393         err = new PrintStream JavaDoc(console2);
394         PipedOutputStream JavaDoc outPipe = new PipedOutputStream JavaDoc();
395         inPipe = new PrintWriter JavaDoc(outPipe);
396         in = new PipedInputStream JavaDoc();
397         try
398         {
399             outPipe.connect(in);
400         }
401         catch (IOException JavaDoc exc)
402         {
403             exc.printStackTrace();
404         }
405         getDocument().addDocumentListener(this);
406         addKeyListener(this);
407         setLineWrap(true);
408         setFont(new Font JavaDoc("Monospaced", 0, 12));
409     }
410
411     void returnPressed()
412     {
413         Document JavaDoc doc = getDocument();
414         int len = doc.getLength();
415         Segment JavaDoc segment = new Segment JavaDoc();
416         try
417         {
418             synchronized (doc)
419             {
420                 doc.getText(outputMark, len - outputMark, segment);
421             }
422         }
423         catch (javax.swing.text.BadLocationException JavaDoc ignored)
424         {
425             ignored.printStackTrace();
426         }
427         if (segment.count > 0)
428         {
429             history.addElement(segment.toString());
430         }
431         historyIndex = history.size();
432         inPipe.write(segment.array, segment.offset, segment.count);
433         append("\n");
434         synchronized (doc)
435         {
436             outputMark = doc.getLength();
437         }
438         inPipe.write("\n");
439         inPipe.flush();
440         console1.flush();
441     }
442
443     public void eval(String JavaDoc str)
444     {
445         inPipe.write(str);
446         inPipe.write("\n");
447         inPipe.flush();
448         console1.flush();
449     }
450
451     public void keyPressed(KeyEvent JavaDoc e)
452     {
453         int code = e.getKeyCode();
454         if (code == KeyEvent.VK_BACK_SPACE || code == KeyEvent.VK_LEFT)
455         {
456             if (outputMark == getCaretPosition())
457             {
458                 e.consume();
459             }
460         }
461         else if (code == KeyEvent.VK_HOME)
462         {
463             int caretPos = getCaretPosition();
464             if (caretPos == outputMark)
465             {
466                 e.consume();
467             }
468             else if (caretPos > outputMark)
469             {
470                 if (!e.isControlDown())
471                 {
472                     if (e.isShiftDown())
473                     {
474                         moveCaretPosition(outputMark);
475                     }
476                     else
477                     {
478                         setCaretPosition(outputMark);
479                     }
480                     e.consume();
481                 }
482             }
483         }
484         else if (code == KeyEvent.VK_ENTER)
485         {
486             returnPressed();
487             e.consume();
488         }
489         else if (code == KeyEvent.VK_UP)
490         {
491             historyIndex--;
492             if (historyIndex >= 0)
493             {
494                 if (historyIndex >= history.size())
495                 {
496                     historyIndex = history.size() - 1;
497                 }
498                 if (historyIndex >= 0)
499                 {
500                     String JavaDoc str = (String JavaDoc) history.elementAt(historyIndex);
501                     int len = getDocument().getLength();
502                     replaceRange(str, outputMark, len);
503                     int caretPos = outputMark + str.length();
504                     select(caretPos, caretPos);
505                 }
506                 else
507                 {
508                     historyIndex++;
509                 }
510             }
511             else
512             {
513                 historyIndex++;
514             }
515             e.consume();
516         }
517         else if (code == KeyEvent.VK_DOWN)
518         {
519             int caretPos = outputMark;
520             if (history.size() > 0)
521             {
522                 historyIndex++;
523                 if (historyIndex < 0)
524                 {
525                     historyIndex = 0;
526                 }
527                 int len = getDocument().getLength();
528                 if (historyIndex < history.size())
529                 {
530                     String JavaDoc str = (String JavaDoc) history.elementAt(historyIndex);
531                     replaceRange(str, outputMark, len);
532                     caretPos = outputMark + str.length();
533                 }
534                 else
535                 {
536                     historyIndex = history.size();
537                     replaceRange("", outputMark, len);
538                 }
539             }
540             select(caretPos, caretPos);
541             e.consume();
542         }
543     }
544
545     public void keyTyped(KeyEvent JavaDoc e)
546     {
547         int keyChar = e.getKeyChar();
548         if (keyChar == 0x8 /* KeyEvent.VK_BACK_SPACE */)
549         {
550             if (outputMark == getCaretPosition())
551             {
552                 e.consume();
553             }
554         }
555         else if (getCaretPosition() < outputMark)
556         {
557             setCaretPosition(outputMark);
558         }
559     }
560
561     public void keyReleased(KeyEvent JavaDoc e)
562     {
563     }
564
565     public synchronized void write(String JavaDoc str)
566     {
567         insert(str, outputMark);
568         int len = str.length();
569         outputMark += len;
570         select(outputMark, outputMark);
571     }
572
573     public synchronized void insertUpdate(DocumentEvent JavaDoc e)
574     {
575         int len = e.getLength();
576         int off = e.getOffset();
577         if (outputMark > off)
578         {
579             outputMark += len;
580         }
581     }
582
583     public synchronized void removeUpdate(DocumentEvent JavaDoc e)
584     {
585         int len = e.getLength();
586         int off = e.getOffset();
587         if (outputMark > off)
588         {
589             if (outputMark >= off + len)
590             {
591                 outputMark -= len;
592             }
593             else
594             {
595                 outputMark = off;
596             }
597         }
598     }
599
600     public void postUpdateUI()
601     {
602         // this attempts to cleanup the damage done by updateComponentTreeUI
603
requestFocus();
604         setCaret(getCaret());
605         synchronized (this)
606         {
607             select(outputMark, outputMark);
608         }
609     }
610
611     public void changedUpdate(DocumentEvent JavaDoc e)
612     {
613     }
614
615     public InputStream JavaDoc getIn()
616     {
617         return in;
618     }
619
620     public PrintStream JavaDoc getOut()
621     {
622         return out;
623     }
624
625     public PrintStream JavaDoc getErr()
626     {
627         return err;
628     }
629
630 }
Popular Tags