JAL-1620 version bump and release notes
[jalview.git] / src / jalview / util / AWTConsole.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2b1)
3  * Copyright (C) 2014 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.io.*;
34 import java.awt.*;
35 import java.awt.event.*;
36
37 public class AWTConsole extends WindowAdapter implements WindowListener,
38         ActionListener, Runnable
39 {
40   private Frame frame;
41
42   private TextArea textArea;
43
44   private Thread reader;
45
46   private Thread reader2;
47
48   private boolean quit;
49
50   private final PipedInputStream pin = new PipedInputStream();
51
52   private final PipedInputStream pin2 = new PipedInputStream();
53
54   Thread errorThrower; // just for testing (Throws an Exception at this Console
55
56   public AWTConsole()
57   {
58     // create all components and add them
59     frame = new Frame("Java Console");
60     Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
61     Dimension frameSize = new Dimension((int) (screenSize.width / 2),
62             (int) (screenSize.height / 2));
63     int x = (int) (frameSize.width / 2);
64     int y = (int) (frameSize.height / 2);
65     frame.setBounds(x, y, frameSize.width, frameSize.height);
66
67     textArea = new TextArea();
68     textArea.setEditable(false);
69     Button button = new Button("clear");
70
71     Panel panel = new Panel();
72     panel.setLayout(new BorderLayout());
73     panel.add(textArea, BorderLayout.CENTER);
74     panel.add(button, BorderLayout.SOUTH);
75     frame.add(panel);
76
77     frame.setVisible(true);
78
79     frame.addWindowListener(this);
80     button.addActionListener(this);
81
82     try
83     {
84       PipedOutputStream pout = new PipedOutputStream(this.pin);
85       System.setOut(new PrintStream(pout, true));
86     } catch (java.io.IOException io)
87     {
88       textArea.append("Couldn't redirect STDOUT to this console\n"
89               + io.getMessage());
90     } catch (SecurityException se)
91     {
92       textArea.append("Couldn't redirect STDOUT to this console\n"
93               + se.getMessage());
94     }
95
96     try
97     {
98       PipedOutputStream pout2 = new PipedOutputStream(this.pin2);
99       System.setErr(new PrintStream(pout2, true));
100     } catch (java.io.IOException io)
101     {
102       textArea.append("Couldn't redirect STDERR to this console\n"
103               + io.getMessage());
104     } catch (SecurityException se)
105     {
106       textArea.append("Couldn't redirect STDERR to this console\n"
107               + se.getMessage());
108     }
109
110     quit = false; // signals the Threads that they should exit
111
112     // Starting two seperate threads to read from the PipedInputStreams
113     //
114     reader = new Thread(this);
115     reader.setDaemon(true);
116     reader.start();
117     //
118     reader2 = new Thread(this);
119     reader2.setDaemon(true);
120     reader2.start();
121
122     // testing part
123     // you may omit this part for your application
124     //
125     System.out.println("Hello World 2");
126     System.out.println("All fonts available to Graphic2D:\n");
127     GraphicsEnvironment ge = GraphicsEnvironment
128             .getLocalGraphicsEnvironment();
129     String[] fontNames = ge.getAvailableFontFamilyNames();
130     for (int n = 0; n < fontNames.length; n++)
131       System.out.println(fontNames[n]);
132     // Testing part: simple an error thrown anywhere in this JVM will be printed
133     // on the Console
134     // We do it with a seperate Thread becasue we don't wan't to break a Thread
135     // used by the Console.
136     System.out.println("\nLets throw an error on this console");
137     errorThrower = new Thread(this);
138     errorThrower.setDaemon(true);
139     errorThrower.start();
140   }
141
142   public synchronized void windowClosed(WindowEvent evt)
143   {
144     quit = true;
145     this.notifyAll(); // stop all threads
146     try
147     {
148       reader.join(1000);
149       pin.close();
150     } catch (Exception e)
151     {
152     }
153     try
154     {
155       reader2.join(1000);
156       pin2.close();
157     } catch (Exception e)
158     {
159     }
160     System.exit(0);
161   }
162
163   public synchronized void windowClosing(WindowEvent evt)
164   {
165     frame.setVisible(false); // default behaviour of JFrame
166     frame.dispose();
167   }
168
169   public synchronized void actionPerformed(ActionEvent evt)
170   {
171     textArea.setText("");
172   }
173
174   public synchronized void run()
175   {
176     try
177     {
178       while (Thread.currentThread() == reader)
179       {
180         try
181         {
182           this.wait(100);
183         } catch (InterruptedException ie)
184         {
185         }
186         if (pin.available() != 0)
187         {
188           String input = this.readLine(pin);
189           textArea.append(input);
190         }
191         if (quit)
192           return;
193       }
194
195       while (Thread.currentThread() == reader2)
196       {
197         try
198         {
199           this.wait(100);
200         } catch (InterruptedException ie)
201         {
202         }
203         if (pin2.available() != 0)
204         {
205           String input = this.readLine(pin2);
206           textArea.append(input);
207         }
208         if (quit)
209           return;
210       }
211     } catch (Exception e)
212     {
213       textArea.append("\nConsole reports an Internal error.");
214       textArea.append("The error is: " + e);
215     }
216
217     // just for testing (Throw a Nullpointer after 1 second)
218     if (Thread.currentThread() == errorThrower)
219     {
220       try
221       {
222         this.wait(1000);
223       } catch (InterruptedException ie)
224       {
225       }
226       throw new NullPointerException(MessageManager.getString("exception.application_test_npe"));
227     }
228
229   }
230
231   public synchronized String readLine(PipedInputStream in)
232           throws IOException
233   {
234     String input = "";
235     do
236     {
237       int available = in.available();
238       if (available == 0)
239         break;
240       byte b[] = new byte[available];
241       in.read(b);
242       input = input + new String(b, 0, b.length);
243     } while (!input.endsWith("\n") && !input.endsWith("\r\n") && !quit);
244     return input;
245   }
246
247   public static void main(String[] arg)
248   {
249     new AWTConsole(); // create console with not reference
250   }
251 }