2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.1)
3 * Copyright (C) 2014 The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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 * The Jalview Authors are detailed in the 'AUTHORS' file.
21 import jalview.util.MessageManager;
25 import java.awt.event.*;
28 import org.apache.log4j.SimpleLayout;
31 * Simple Jalview Java Console. Version 1 - allows viewing of console output
32 * after desktop is created. Acquired with thanks from RJHM's site
33 * http://www.comweb.nl/java/Console/Console.html A simple Java Console for your
34 * application (Swing version) Requires Java 1.1.5 or higher Disclaimer the use
35 * of this source is at your own risk. Permision to use and distribute into your
36 * own applications RJHM van den Bergh , rvdb@comweb.nl
39 public class Console extends WindowAdapter implements WindowListener,
40 ActionListener, Runnable
44 private JTextArea textArea;
47 * unused - tally and limit for lines in console window int lines = 0;
51 int byteslim = 102400, bytescut = 76800; // 100k and 75k cut point.
53 private Thread reader, reader2, textAppender;
57 private final PrintStream stdout = System.out, stderr = System.err;
59 private PipedInputStream pin = new PipedInputStream();
61 private PipedInputStream pin2 = new PipedInputStream();
63 private StringBuffer displayPipe = new StringBuffer();
65 Thread errorThrower; // just for testing (Throws an Exception at this Console
67 // are we attached to some parent Desktop
68 Desktop parent = null;
72 // create all components and add them
73 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
74 frame = initFrame("Java Console", screenSize.width / 2,
75 screenSize.height / 2, -1, -1);
79 private void initConsole(boolean visible)
81 initConsole(visible, true);
91 private void initConsole(boolean visible, boolean redirect)
93 // CutAndPasteTransfer cpt = new CutAndPasteTransfer();
94 // textArea = cpt.getTextArea();
95 textArea = new JTextArea();
96 textArea.setEditable(false);
97 JButton button = new JButton(MessageManager.getString("action.clear"));
100 frame.getContentPane().setLayout(new BorderLayout());
101 frame.getContentPane().add(new JScrollPane(textArea),
102 BorderLayout.CENTER);
103 frame.getContentPane().add(button, BorderLayout.SOUTH);
104 frame.setVisible(visible);
105 updateConsole = visible;
106 frame.addWindowListener(this);
107 button.addActionListener(this);
116 quit = false; // signals the Threads that they should exit
118 // Starting two seperate threads to read from the PipedInputStreams
120 reader = new Thread(this);
121 reader.setDaemon(true);
124 reader2 = new Thread(this);
125 reader2.setDaemon(true);
127 // and a thread to append text to the textarea
128 textAppender = new Thread(this);
129 textAppender.setDaemon(true);
130 textAppender.start();
133 PipedOutputStream pout = null, perr = null;
135 public void redirectStreams()
141 pout = new PipedOutputStream(this.pin);
142 System.setOut(new PrintStream(pout, true));
143 } catch (java.io.IOException io)
145 textArea.append("Couldn't redirect STDOUT to this console\n"
147 io.printStackTrace(stderr);
148 } catch (SecurityException se)
150 textArea.append("Couldn't redirect STDOUT to this console\n"
152 se.printStackTrace(stderr);
157 perr = new PipedOutputStream(this.pin2);
158 System.setErr(new PrintStream(perr, true));
159 } catch (java.io.IOException io)
161 textArea.append("Couldn't redirect STDERR to this console\n"
163 io.printStackTrace(stderr);
164 } catch (SecurityException se)
166 textArea.append("Couldn't redirect STDERR to this console\n"
168 se.printStackTrace(stderr);
173 public void unredirectStreams()
179 System.setOut(stdout);
182 pin = new PipedInputStream();
184 } catch (java.io.IOException io)
186 textArea.append("Couldn't unredirect STDOUT to this console\n"
188 io.printStackTrace(stderr);
189 } catch (SecurityException se)
191 textArea.append("Couldn't unredirect STDOUT to this console\n"
193 se.printStackTrace(stderr);
198 System.setErr(stderr);
201 pin2 = new PipedInputStream();
203 } catch (java.io.IOException io)
205 textArea.append("Couldn't unredirect STDERR to this console\n"
207 io.printStackTrace(stderr);
208 } catch (SecurityException se)
210 textArea.append("Couldn't unredirect STDERR to this console\n"
212 se.printStackTrace(stderr);
220 // you may omit this part for your application
223 System.out.println("Hello World 2");
224 System.out.println("All fonts available to Graphic2D:\n");
225 GraphicsEnvironment ge = GraphicsEnvironment
226 .getLocalGraphicsEnvironment();
227 String[] fontNames = ge.getAvailableFontFamilyNames();
228 for (int n = 0; n < fontNames.length; n++)
229 System.out.println(fontNames[n]);
230 // Testing part: simple an error thrown anywhere in this JVM will be printed
232 // We do it with a seperate Thread becasue we don't wan't to break a Thread
233 // used by the Console.
234 System.out.println("\nLets throw an error on this console");
235 errorThrower = new Thread(this);
236 errorThrower.setDaemon(true);
237 errorThrower.start();
240 private JFrame initFrame(String string, int i, int j, int x, int y)
242 JFrame frame = new JFrame(string);
243 frame.setName(string);
248 frame.setBounds(x, y, i, j);
253 * attach a console to the desktop - the desktop will open it if requested.
257 public Console(Desktop desktop)
263 * attach a console to the desktop - the desktop will open it if requested.
266 * @param showjconsole
267 * - if true, then redirect stdout immediately
269 public Console(Desktop desktop, boolean showjconsole)
272 // window name - get x,y,width, height possibly scaled
273 Rectangle bounds = desktop.getLastKnownDimensions("JAVA_CONSOLE_");
276 frame = initFrame("Jalview Java Console", desktop.getWidth() / 2,
277 desktop.getHeight() / 4, desktop.getX(), desktop.getY());
281 frame = initFrame("Jalview Java Console", bounds.width,
282 bounds.height, bounds.x, bounds.y);
284 // desktop.add(frame);
286 JalviewAppender jappender = new JalviewAppender();
287 jappender.setLayout(new SimpleLayout());
288 JalviewAppender.setTextArea(textArea);
289 org.apache.log4j.Logger.getRootLogger().addAppender(jappender);
292 public synchronized void stopConsole()
297 * reader.notify(); reader2.notify(); if (errorThrower!=null)
298 * errorThrower.notify(); // stop all threads if (textAppender!=null)
299 * textAppender.notify();
307 } catch (Exception e)
314 } catch (Exception e)
319 textAppender.join(10);
320 } catch (Exception e)
324 if (!frame.isVisible())
331 public synchronized void windowClosed(WindowEvent evt)
333 frame.setVisible(false);
337 private void closeConsoleGui()
339 updateConsole = false;
347 parent.showConsole(false);
351 public synchronized void windowClosing(WindowEvent evt)
353 frame.setVisible(false); // default behaviour of JFrame
359 public synchronized void actionPerformed(ActionEvent evt)
362 // textArea.setText("");
365 public synchronized void run()
369 while (Thread.currentThread() == reader)
371 if (pin == null || pin.available() == 0)
376 if (pin.available() == 0)
380 } catch (InterruptedException ie)
385 while (pin.available() != 0)
387 String input = this.readLine(pin);
389 long time = System.nanoTime();
390 appendToTextArea(input);
391 // stderr.println("Time taken to stdout append:\t"
392 // + (System.nanoTime() - time) + " ns");
399 while (Thread.currentThread() == reader2)
401 if (pin2.available() == 0)
406 if (pin2.available() == 0)
410 } catch (InterruptedException ie)
414 while (pin2.available() != 0)
416 String input = this.readLine(pin2);
418 long time = System.nanoTime();
419 appendToTextArea(input);
420 // stderr.println("Time taken to stderr append:\t"
421 // + (System.nanoTime() - time) + " ns");
427 while (Thread.currentThread() == textAppender)
431 // check string buffer - if greater than console, clear console and
432 // replace with last segment of content, otherwise, append all to
435 while (displayPipe.length() > 0)
438 StringBuffer tmp = new StringBuffer(), replace;
439 synchronized (displayPipe)
441 replace = displayPipe;
444 // simply append whole buffer
445 textArea.append(replace.toString());
446 count += replace.length();
447 if (count > byteslim)
452 if (displayPipe.length() == 0)
457 if (displayPipe.length() == 0)
461 } catch (InterruptedException e)
472 } catch (InterruptedException e)
483 } catch (Exception e)
485 textArea.append("\nConsole reports an Internal error.");
486 textArea.append("The error is: " + e.getMessage());
487 // Need to uncomment this to ensure that line tally is synched.
489 stderr.println("Console reports an Internal error.\nThe error is: "
493 // just for testing (Throw a Nullpointer after 1 second)
494 if (Thread.currentThread() == errorThrower)
499 } catch (InterruptedException ie)
502 throw new NullPointerException(
503 "Application test: throwing an NullPointerException It should arrive at the console");
507 private void appendToTextArea(final String input)
509 if (updateConsole == false)
514 long time = System.nanoTime();
515 javax.swing.SwingUtilities.invokeLater(new Runnable()
519 displayPipe.append(input); // change to stringBuffer
520 // displayPipe.flush();
524 // stderr.println("Time taken to Spawnappend:\t" + (System.nanoTime() -
529 private String header = null;
531 private boolean updateConsole = false;
533 private synchronized void trimBuffer(boolean clear)
535 if (header == null && textArea.getLineCount() > 5)
539 header = textArea.getText(0, textArea.getLineStartOffset(5))
540 + "\nTruncated...\n";
541 } catch (Exception e)
547 int tlength = textArea.getDocument().getLength();
550 if (clear || (tlength > byteslim))
556 long time = System.nanoTime();
557 textArea.replaceRange(header, 0, tlength - bytescut);
558 // stderr.println("Time taken to cut:\t"
559 // + (System.nanoTime() - time) + " ns");
563 textArea.setText(header);
565 } catch (Exception e)
569 // lines = textArea.getLineCount();
575 public synchronized String readLine(PipedInputStream in)
582 int available = in.available();
585 byte b[] = new byte[available];
587 input = input + new String(b, 0, b.length);
588 // counts lines - we don't do this for speed.
589 // while ((lp = input.indexOf("\n", lp + 1)) > -1)
593 } while (!input.endsWith("\n") && !input.endsWith("\r\n") && !quit);
597 public static void main(String[] arg)
599 new Console().test(); // create console with not reference
603 public void setVisible(boolean selected)
605 frame.setVisible(selected);
606 if (selected == true)
609 updateConsole = true;
615 updateConsole = false;
619 public Rectangle getBounds()
623 return frame.getBounds();
629 * set the banner that appears at the top of the console output
633 public void setHeader(String string)
636 if (header.charAt(header.length() - 1) != '\n')
640 textArea.insert(header, 0);
648 public String getHeader()