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