Merge branch 'develop' into features/r2_11_2/JAL-3829_3dbeacons
[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.exit(0);
178   }
179
180   @Override
181   public synchronized void windowClosing(WindowEvent evt)
182   {
183     frame.setVisible(false); // default behaviour of JFrame
184     frame.dispose();
185   }
186
187   @Override
188   public synchronized void actionPerformed(ActionEvent evt)
189   {
190     textArea.setText("");
191   }
192
193   @Override
194   public synchronized void run()
195   {
196     try
197     {
198       while (Thread.currentThread() == reader)
199       {
200         try
201         {
202           this.wait(100);
203         } catch (InterruptedException ie)
204         {
205         }
206         if (pin.available() != 0)
207         {
208           String input = this.readLine(pin);
209           textArea.append(input);
210         }
211         if (quit)
212         {
213           return;
214         }
215       }
216
217       while (Thread.currentThread() == reader2)
218       {
219         try
220         {
221           this.wait(100);
222         } catch (InterruptedException ie)
223         {
224         }
225         if (pin2.available() != 0)
226         {
227           String input = this.readLine(pin2);
228           textArea.append(input);
229         }
230         if (quit)
231         {
232           return;
233         }
234       }
235     } catch (Exception e)
236     {
237       textArea.append("\nConsole reports an Internal error.");
238       textArea.append("The error is: " + e);
239     }
240
241     // just for testing (Throw a Nullpointer after 1 second)
242     if (Thread.currentThread() == errorThrower)
243     {
244       try
245       {
246         this.wait(1000);
247       } catch (InterruptedException ie)
248       {
249       }
250       throw new NullPointerException(
251               MessageManager.getString("exception.application_test_npe"));
252     }
253
254   }
255
256   public synchronized String readLine(PipedInputStream in)
257           throws IOException
258   {
259     String input = "";
260     do
261     {
262       int available = in.available();
263       if (available == 0)
264       {
265         break;
266       }
267       byte b[] = new byte[available];
268       in.read(b);
269       input = input + new String(b, 0, b.length);
270     } while (!input.endsWith("\n") && !input.endsWith("\r\n") && !quit);
271     return input;
272   }
273
274   /**
275    * 
276    * @param arg
277    * @j2sIgnore
278    */
279   public static void main(String[] arg)
280   {
281     new AWTConsole(); // create console with not reference
282   }
283 }