JAL-629 Commands more objecty, less classy. FileLoader with sync option (or rather...
[jalview.git] / src / jalview / util / AWTConsole.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.util;
22
23 //
24 // A simple Java Console for your application (Swing version)
25 // Requires Java 1.1.5 or higher
26 //
27 // Disclaimer the use of this source is at your own risk. 
28 //
29 // Permision to use and distribute into your own applications
30 //
31 // RJHM van den Bergh , rvdb@comweb.nl
32
33 import java.awt.BorderLayout;
34 import java.awt.Button;
35 import java.awt.Dimension;
36 import java.awt.Frame;
37 import java.awt.GraphicsEnvironment;
38 import java.awt.Panel;
39 import java.awt.TextArea;
40 import java.awt.Toolkit;
41 import java.awt.event.ActionEvent;
42 import java.awt.event.ActionListener;
43 import java.awt.event.WindowAdapter;
44 import java.awt.event.WindowEvent;
45 import java.awt.event.WindowListener;
46 import java.io.IOException;
47 import java.io.PipedInputStream;
48 import java.io.PipedOutputStream;
49 import java.io.PrintStream;
50
51 public class AWTConsole extends WindowAdapter
52         implements WindowListener, ActionListener, Runnable
53 {
54   private Frame frame;
55
56   private TextArea textArea;
57
58   private Thread reader;
59
60   private Thread reader2;
61
62   private boolean quit;
63
64   private final PipedInputStream pin = new PipedInputStream();
65
66   private final PipedInputStream pin2 = new PipedInputStream();
67
68   Thread errorThrower; // just for testing (Throws an Exception at this Console
69
70   public AWTConsole()
71   {
72     // create all components and add them
73     frame = new Frame("Java Console");
74     Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
75     Dimension frameSize = new Dimension(screenSize.width / 2,
76             screenSize.height / 2);
77     int x = frameSize.width / 2;
78     int y = frameSize.height / 2;
79     frame.setBounds(x, y, frameSize.width, frameSize.height);
80
81     textArea = new TextArea();
82     textArea.setEditable(false);
83     Button button = new Button("clear");
84
85     Panel panel = new Panel();
86     panel.setLayout(new BorderLayout());
87     panel.add(textArea, BorderLayout.CENTER);
88     panel.add(button, BorderLayout.SOUTH);
89     frame.add(panel);
90
91     frame.setVisible(true);
92
93     frame.addWindowListener(this);
94     button.addActionListener(this);
95
96     try
97     {
98       PipedOutputStream pout = new PipedOutputStream(this.pin);
99       System.setOut(new PrintStream(pout, true));
100     } catch (java.io.IOException io)
101     {
102       textArea.append("Couldn't redirect STDOUT to this console\n"
103               + io.getMessage());
104     } catch (SecurityException se)
105     {
106       textArea.append("Couldn't redirect STDOUT to this console\n"
107               + se.getMessage());
108     }
109
110     try
111     {
112       PipedOutputStream pout2 = new PipedOutputStream(this.pin2);
113       System.setErr(new PrintStream(pout2, true));
114     } catch (java.io.IOException io)
115     {
116       textArea.append("Couldn't redirect STDERR to this console\n"
117               + io.getMessage());
118     } catch (SecurityException se)
119     {
120       textArea.append("Couldn't redirect STDERR to this console\n"
121               + se.getMessage());
122     }
123
124     quit = false; // signals the Threads that they should exit
125
126     // Starting two seperate threads to read from the PipedInputStreams
127     //
128     reader = new Thread(this);
129     reader.setDaemon(true);
130     reader.start();
131     //
132     reader2 = new Thread(this);
133     reader2.setDaemon(true);
134     reader2.start();
135
136     // testing part
137     // you may omit this part for your application
138     //
139     System.out.println("Hello World 2");
140     System.out.println("All fonts available to Graphic2D:\n");
141     GraphicsEnvironment ge = GraphicsEnvironment
142             .getLocalGraphicsEnvironment();
143     String[] fontNames = ge.getAvailableFontFamilyNames();
144     for (int n = 0; n < fontNames.length; n++)
145     {
146       System.out.println(fontNames[n]);
147     }
148     // Testing part: simple an error thrown anywhere in this JVM will be printed
149     // on the Console
150     // We do it with a seperate Thread becasue we don't wan't to break a Thread
151     // used by the Console.
152     System.out.println("\nLets throw an error on this console");
153     errorThrower = new Thread(this);
154     errorThrower.setDaemon(true);
155     errorThrower.start();
156   }
157
158   @Override
159   public synchronized void windowClosed(WindowEvent evt)
160   {
161     quit = true;
162     this.notifyAll(); // stop all threads
163     try
164     {
165       reader.join(1000);
166       pin.close();
167     } catch (Exception e)
168     {
169     }
170     try
171     {
172       reader2.join(1000);
173       pin2.close();
174     } catch (Exception e)
175     {
176     }
177     System.out.println("Window closing. Bye!");
178     System.exit(0);
179   }
180
181   @Override
182   public synchronized void windowClosing(WindowEvent evt)
183   {
184     frame.setVisible(false); // default behaviour of JFrame
185     frame.dispose();
186   }
187
188   @Override
189   public synchronized void actionPerformed(ActionEvent evt)
190   {
191     textArea.setText("");
192   }
193
194   @Override
195   public synchronized void run()
196   {
197     try
198     {
199       while (Thread.currentThread() == reader)
200       {
201         try
202         {
203           this.wait(100);
204         } catch (InterruptedException ie)
205         {
206         }
207         if (pin.available() != 0)
208         {
209           String input = this.readLine(pin);
210           textArea.append(input);
211         }
212         if (quit)
213         {
214           return;
215         }
216       }
217
218       while (Thread.currentThread() == reader2)
219       {
220         try
221         {
222           this.wait(100);
223         } catch (InterruptedException ie)
224         {
225         }
226         if (pin2.available() != 0)
227         {
228           String input = this.readLine(pin2);
229           textArea.append(input);
230         }
231         if (quit)
232         {
233           return;
234         }
235       }
236     } catch (Exception e)
237     {
238       textArea.append("\nConsole reports an Internal error.");
239       textArea.append("The error is: " + e);
240     }
241
242     // just for testing (Throw a Nullpointer after 1 second)
243     if (Thread.currentThread() == errorThrower)
244     {
245       try
246       {
247         this.wait(1000);
248       } catch (InterruptedException ie)
249       {
250       }
251       throw new NullPointerException(
252               MessageManager.getString("exception.application_test_npe"));
253     }
254
255   }
256
257   public synchronized String readLine(PipedInputStream in)
258           throws IOException
259   {
260     String input = "";
261     do
262     {
263       int available = in.available();
264       if (available == 0)
265       {
266         break;
267       }
268       byte b[] = new byte[available];
269       in.read(b);
270       input = input + new String(b, 0, b.length);
271     } while (!input.endsWith("\n") && !input.endsWith("\r\n") && !quit);
272     return input;
273   }
274
275   /**
276    * 
277    * @param arg
278    * @j2sIgnore
279    */
280   public static void main(String[] arg)
281   {
282     new AWTConsole(); // create console with not reference
283   }
284 }