Clover icon

jalviewX

  1. Project Clover database Wed Oct 31 2018 15:13:58 GMT
  2. Package jalview.gui

File Console.java

 

Coverage histogram

../../img/srcFileCovDistChart5.png
40% of files have more coverage

Code metrics

76
216
24
1
691
517
86
0.4
9
24
3.58

Classes

Class Line # Actions
Console 56 216 86 163
0.484177248.4%
 

Contributing tests

No tests hitting this source file were found.

Source view

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.gui;
22   
23    import jalview.util.MessageManager;
24   
25    import java.awt.BorderLayout;
26    import java.awt.Dimension;
27    import java.awt.GraphicsEnvironment;
28    import java.awt.Rectangle;
29    import java.awt.Toolkit;
30    import java.awt.event.ActionEvent;
31    import java.awt.event.ActionListener;
32    import java.awt.event.WindowAdapter;
33    import java.awt.event.WindowEvent;
34    import java.awt.event.WindowListener;
35    import java.io.IOException;
36    import java.io.PipedInputStream;
37    import java.io.PipedOutputStream;
38    import java.io.PrintStream;
39   
40    import javax.swing.JButton;
41    import javax.swing.JFrame;
42    import javax.swing.JScrollPane;
43    import javax.swing.JTextArea;
44   
45    import org.apache.log4j.SimpleLayout;
46   
47    /**
48    * Simple Jalview Java Console. Version 1 - allows viewing of console output
49    * after desktop is created. Acquired with thanks from RJHM's site
50    * http://www.comweb.nl/java/Console/Console.html A simple Java Console for your
51    * application (Swing version) Requires Java 1.1.5 or higher Disclaimer the use
52    * of this source is at your own risk. Permision to use and distribute into your
53    * own applications RJHM van den Bergh , rvdb@comweb.nl
54    */
55   
 
56    public class Console extends WindowAdapter
57    implements WindowListener, ActionListener, Runnable
58    {
59    private JFrame frame;
60   
61    private JTextArea textArea;
62   
63    /*
64    * unused - tally and limit for lines in console window int lines = 0;
65    *
66    * int lim = 1000;
67    */
68    int byteslim = 102400, bytescut = 76800; // 100k and 75k cut point.
69   
70    private Thread reader, reader2, textAppender;
71   
72    private boolean quit;
73   
74    private final PrintStream stdout = System.out, stderr = System.err;
75   
76    private PipedInputStream pin = new PipedInputStream();
77   
78    private PipedInputStream pin2 = new PipedInputStream();
79   
80    private StringBuffer displayPipe = new StringBuffer();
81   
82    Thread errorThrower; // just for testing (Throws an Exception at this Console
83   
84    // are we attached to some parent Desktop
85    Desktop parent = null;
86   
87    private int MIN_WIDTH = 300;
88   
89    private int MIN_HEIGHT = 250;
90   
 
91  0 toggle public Console()
92    {
93    // create all components and add them
94  0 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
95  0 frame = initFrame("Java Console", screenSize.width / 2,
96    screenSize.height / 2, -1, -1);
97  0 initConsole(true);
98    }
99   
 
100  11 toggle private void initConsole(boolean visible)
101    {
102  11 initConsole(visible, true);
103    }
104   
105    /**
106    *
107    * @param visible
108    * - open the window
109    * @param redirect
110    * - redirect std*
111    */
 
112  11 toggle private void initConsole(boolean visible, boolean redirect)
113    {
114    // CutAndPasteTransfer cpt = new CutAndPasteTransfer();
115    // textArea = cpt.getTextArea();
116  11 textArea = new JTextArea();
117  11 textArea.setEditable(false);
118  11 JButton button = new JButton(MessageManager.getString("action.clear"));
119   
120    // frame = cpt;
121  11 frame.getContentPane().setLayout(new BorderLayout());
122  11 frame.getContentPane().add(new JScrollPane(textArea),
123    BorderLayout.CENTER);
124  11 frame.getContentPane().add(button, BorderLayout.SOUTH);
125  11 frame.setVisible(visible);
126  11 updateConsole = visible;
127  11 frame.addWindowListener(this);
128  11 button.addActionListener(this);
129  11 if (redirect)
130    {
131  11 redirectStreams();
132    }
133    else
134    {
135  0 unredirectStreams();
136    }
137  11 quit = false; // signals the Threads that they should exit
138   
139    // Starting two seperate threads to read from the PipedInputStreams
140    //
141  11 reader = new Thread(this);
142  11 reader.setDaemon(true);
143  11 reader.start();
144    //
145  11 reader2 = new Thread(this);
146  11 reader2.setDaemon(true);
147  11 reader2.start();
148    // and a thread to append text to the textarea
149  11 textAppender = new Thread(this);
150  11 textAppender.setDaemon(true);
151  11 textAppender.start();
152    }
153   
154    PipedOutputStream pout = null, perr = null;
155   
 
156  11 toggle public void redirectStreams()
157    {
158  11 if (pout == null)
159    {
160  11 try
161    {
162  11 pout = new PipedOutputStream(this.pin);
163  11 System.setOut(new PrintStream(pout, true));
164    } catch (java.io.IOException io)
165    {
166  0 textArea.append("Couldn't redirect STDOUT to this console\n"
167    + io.getMessage());
168  0 io.printStackTrace(stderr);
169    } catch (SecurityException se)
170    {
171  0 textArea.append("Couldn't redirect STDOUT to this console\n"
172    + se.getMessage());
173  0 se.printStackTrace(stderr);
174    }
175   
176  11 try
177    {
178  11 perr = new PipedOutputStream(this.pin2);
179  11 System.setErr(new PrintStream(perr, true));
180    } catch (java.io.IOException io)
181    {
182  0 textArea.append("Couldn't redirect STDERR to this console\n"
183    + io.getMessage());
184  0 io.printStackTrace(stderr);
185    } catch (SecurityException se)
186    {
187  0 textArea.append("Couldn't redirect STDERR to this console\n"
188    + se.getMessage());
189  0 se.printStackTrace(stderr);
190    }
191    }
192    }
193   
 
194  11 toggle public void unredirectStreams()
195    {
196  11 if (pout != null)
197    {
198  11 try
199    {
200  11 System.setOut(stdout);
201  11 pout.flush();
202  11 pout.close();
203  11 pin = new PipedInputStream();
204  11 pout = null;
205    } catch (java.io.IOException io)
206    {
207  0 textArea.append("Couldn't unredirect STDOUT to this console\n"
208    + io.getMessage());
209  0 io.printStackTrace(stderr);
210    } catch (SecurityException se)
211    {
212  0 textArea.append("Couldn't unredirect STDOUT to this console\n"
213    + se.getMessage());
214  0 se.printStackTrace(stderr);
215    }
216   
217  11 try
218    {
219  11 System.setErr(stderr);
220  11 perr.flush();
221  11 perr.close();
222  11 pin2 = new PipedInputStream();
223  11 perr = null;
224    } catch (java.io.IOException io)
225    {
226  0 textArea.append("Couldn't unredirect STDERR to this console\n"
227    + io.getMessage());
228  0 io.printStackTrace(stderr);
229    } catch (SecurityException se)
230    {
231  0 textArea.append("Couldn't unredirect STDERR to this console\n"
232    + se.getMessage());
233  0 se.printStackTrace(stderr);
234    }
235    }
236    }
237   
 
238  0 toggle public void test()
239    {
240    // testing part
241    // you may omit this part for your application
242    //
243   
244  0 System.out.println("Hello World 2");
245  0 System.out.println("All fonts available to Graphic2D:\n");
246  0 GraphicsEnvironment ge = GraphicsEnvironment
247    .getLocalGraphicsEnvironment();
248  0 String[] fontNames = ge.getAvailableFontFamilyNames();
249  0 for (int n = 0; n < fontNames.length; n++)
250    {
251  0 System.out.println(fontNames[n]);
252    }
253    // Testing part: simple an error thrown anywhere in this JVM will be printed
254    // on the Console
255    // We do it with a seperate Thread becasue we don't wan't to break a Thread
256    // used by the Console.
257  0 System.out.println("\nLets throw an error on this console");
258  0 errorThrower = new Thread(this);
259  0 errorThrower.setDaemon(true);
260  0 errorThrower.start();
261    }
262   
 
263  11 toggle private JFrame initFrame(String string, int i, int j, int x, int y)
264    {
265  11 JFrame frame = new JFrame(string);
266  11 frame.setName(string);
267  11 if (x == -1)
268    {
269  0 x = i / 2;
270    }
271  11 if (y == -1)
272    {
273  0 y = j / 2;
274    }
275  11 frame.setBounds(x, y, i, j);
276  11 return frame;
277    }
278   
279    /**
280    * attach a console to the desktop - the desktop will open it if requested.
281    *
282    * @param desktop
283    */
 
284  0 toggle public Console(Desktop desktop)
285    {
286  0 this(desktop, true);
287    }
288   
289    /**
290    * attach a console to the desktop - the desktop will open it if requested.
291    *
292    * @param desktop
293    * @param showjconsole
294    * - if true, then redirect stdout immediately
295    */
 
296  11 toggle public Console(Desktop desktop, boolean showjconsole)
297    {
298  11 parent = desktop;
299    // window name - get x,y,width, height possibly scaled
300  11 Rectangle bounds = desktop.getLastKnownDimensions("JAVA_CONSOLE_");
301  11 if (bounds == null)
302    {
303  4 frame = initFrame("Jalview Java Console", desktop.getWidth() / 2,
304    desktop.getHeight() / 4, desktop.getX(), desktop.getY());
305    }
306    else
307    {
308  7 frame = initFrame("Jalview Java Console", bounds.width, bounds.height,
309    bounds.x, bounds.y);
310    }
311  11 frame.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
312    // desktop.add(frame);
313  11 initConsole(false);
314  11 JalviewAppender jappender = new JalviewAppender();
315  11 jappender.setLayout(new SimpleLayout());
316  11 JalviewAppender.setTextArea(textArea);
317  11 org.apache.log4j.Logger.getRootLogger().addAppender(jappender);
318    }
319   
 
320  0 toggle public synchronized void stopConsole()
321    {
322  0 quit = true;
323  0 this.notifyAll();
324    /*
325    * reader.notify(); reader2.notify(); if (errorThrower!=null)
326    * errorThrower.notify(); // stop all threads if (textAppender!=null)
327    * textAppender.notify();
328    */
329  0 if (pout != null)
330    {
331  0 try
332    {
333  0 reader.join(10);
334  0 pin.close();
335    } catch (Exception e)
336    {
337    }
338  0 try
339    {
340  0 reader2.join(10);
341  0 pin2.close();
342    } catch (Exception e)
343    {
344    }
345  0 try
346    {
347  0 textAppender.join(10);
348    } catch (Exception e)
349    {
350    }
351    }
352  0 if (!frame.isVisible())
353    {
354  0 frame.dispose();
355    }
356    // System.exit(0);
357    }
358   
 
359  0 toggle @Override
360    public synchronized void windowClosed(WindowEvent evt)
361    {
362  0 frame.setVisible(false);
363  0 closeConsoleGui();
364    }
365   
 
366  0 toggle private void closeConsoleGui()
367    {
368  0 updateConsole = false;
369  0 if (parent == null)
370    {
371   
372  0 stopConsole();
373    }
374    else
375    {
376  0 parent.showConsole(false);
377    }
378    }
379   
 
380  0 toggle @Override
381    public synchronized void windowClosing(WindowEvent evt)
382    {
383  0 frame.setVisible(false); // default behaviour of JFrame
384  0 closeConsoleGui();
385   
386    // frame.dispose();
387    }
388   
 
389  0 toggle @Override
390    public synchronized void actionPerformed(ActionEvent evt)
391    {
392  0 trimBuffer(true);
393    // textArea.setText("");
394    }
395   
 
396  33 toggle @Override
397    public synchronized void run()
398    {
399  33 try
400    {
401  4615 while (Thread.currentThread() == reader)
402    {
403  4592 if (pin == null || pin.available() == 0)
404    {
405  4593 try
406    {
407  4594 this.wait(100);
408  4582 if (pin.available() == 0)
409    {
410  4583 trimBuffer(false);
411    }
412    } catch (InterruptedException ie)
413    {
414    }
415    }
416   
417  4582 while (pin.available() != 0)
418    {
419  0 String input = this.readLine(pin);
420  0 stdout.print(input);
421  0 long time = System.nanoTime();
422  0 appendToTextArea(input);
423    // stderr.println("Time taken to stdout append:\t"
424    // + (System.nanoTime() - time) + " ns");
425    // lines++;
426    }
427  4583 if (quit)
428    {
429  0 return;
430    }
431    }
432   
433  4604 while (Thread.currentThread() == reader2)
434    {
435  4596 if (pin2.available() == 0)
436    {
437  4596 try
438    {
439  4595 this.wait(100);
440  4585 if (pin2.available() == 0)
441    {
442  4585 trimBuffer(false);
443    }
444    } catch (InterruptedException ie)
445    {
446    }
447    }
448  4586 while (pin2.available() != 0)
449    {
450  1 String input = this.readLine(pin2);
451  1 stderr.print(input);
452  1 long time = System.nanoTime();
453  1 appendToTextArea(input);
454    // stderr.println("Time taken to stderr append:\t"
455    // + (System.nanoTime() - time) + " ns");
456    // lines++;
457    }
458  4585 if (quit)
459    {
460  0 return;
461    }
462    }
463  4590 while (Thread.currentThread() == textAppender)
464    {
465  4588 if (updateConsole)
466    {
467    // check string buffer - if greater than console, clear console and
468    // replace with last segment of content, otherwise, append all to
469    // content.
470  0 long count;
471  0 while (displayPipe.length() > 0)
472    {
473  0 count = 0;
474  0 StringBuffer tmp = new StringBuffer(), replace;
475  0 synchronized (displayPipe)
476    {
477  0 replace = displayPipe;
478  0 displayPipe = tmp;
479    }
480    // simply append whole buffer
481  0 textArea.append(replace.toString());
482  0 count += replace.length();
483  0 if (count > byteslim)
484    {
485  0 trimBuffer(false);
486    }
487    }
488  0 if (displayPipe.length() == 0)
489    {
490  0 try
491    {
492  0 this.wait(100);
493  0 if (displayPipe.length() == 0)
494    {
495  0 trimBuffer(false);
496    }
497    } catch (InterruptedException e)
498    {
499    }
500  0 ;
501    }
502    }
503    else
504    {
505  4590 try
506    {
507  4590 this.wait(100);
508    } catch (InterruptedException e)
509    {
510   
511    }
512    }
513  4578 if (quit)
514    {
515  0 return;
516    }
517   
518    }
519    } catch (Exception e)
520    {
521  0 textArea.append("\nConsole reports an Internal error.");
522  0 textArea.append("The error is: " + e.getMessage());
523    // Need to uncomment this to ensure that line tally is synched.
524    // lines += 2;
525  0 stderr.println(
526    "Console reports an Internal error.\nThe error is: " + e);
527    }
528   
529    // just for testing (Throw a Nullpointer after 1 second)
530  0 if (Thread.currentThread() == errorThrower)
531    {
532  0 try
533    {
534  0 this.wait(1000);
535    } catch (InterruptedException ie)
536    {
537    }
538  0 throw new NullPointerException(
539    MessageManager.getString("exception.application_test_npe"));
540    }
541    }
542   
 
543  1 toggle private void appendToTextArea(final String input)
544    {
545  1 if (updateConsole == false)
546    {
547    // do nothing;
548  1 return;
549    }
550  0 long time = System.nanoTime();
551  0 javax.swing.SwingUtilities.invokeLater(new Runnable()
552    {
 
553  0 toggle @Override
554    public void run()
555    {
556  0 displayPipe.append(input); // change to stringBuffer
557    // displayPipe.flush();
558   
559    }
560    });
561    // stderr.println("Time taken to Spawnappend:\t" + (System.nanoTime() -
562    // time)
563    // + " ns");
564    }
565   
566    private String header = null;
567   
568    private boolean updateConsole = false;
569   
 
570  9152 toggle private synchronized void trimBuffer(boolean clear)
571    {
572  9149 if (header == null && textArea.getLineCount() > 5)
573    {
574  0 try
575    {
576  0 header = textArea.getText(0, textArea.getLineStartOffset(5))
577    + "\nTruncated...\n";
578    } catch (Exception e)
579    {
580  0 e.printStackTrace();
581    }
582    }
583    // trim the buffer
584  9149 int tlength = textArea.getDocument().getLength();
585  9158 if (header != null)
586    {
587  9157 if (clear || (tlength > byteslim))
588    {
589  0 try
590    {
591  0 if (!clear)
592    {
593  0 long time = System.nanoTime();
594  0 textArea.replaceRange(header, 0, tlength - bytescut);
595    // stderr.println("Time taken to cut:\t"
596    // + (System.nanoTime() - time) + " ns");
597    }
598    else
599    {
600  0 textArea.setText(header);
601    }
602    } catch (Exception e)
603    {
604  0 e.printStackTrace();
605    }
606    // lines = textArea.getLineCount();
607    }
608    }
609   
610    }
611   
 
612  1 toggle public synchronized String readLine(PipedInputStream in)
613    throws IOException
614    {
615  1 String input = "";
616  1 int lp = -1;
617  1 do
618    {
619  1 int available = in.available();
620  1 if (available == 0)
621    {
622  0 break;
623    }
624  1 byte b[] = new byte[available];
625  1 in.read(b);
626  1 input = input + new String(b, 0, b.length);
627    // counts lines - we don't do this for speed.
628    // while ((lp = input.indexOf("\n", lp + 1)) > -1)
629    // {
630    // lines++;
631    // }
632  1 } while (!input.endsWith("\n") && !input.endsWith("\r\n") && !quit);
633  1 return input;
634    }
635   
 
636  0 toggle public static void main(String[] arg)
637    {
638  0 new Console().test(); // create console with not reference
639   
640    }
641   
 
642  11 toggle public void setVisible(boolean selected)
643    {
644  11 frame.setVisible(selected);
645  11 if (selected == true)
646    {
647  0 redirectStreams();
648  0 updateConsole = true;
649  0 frame.toFront();
650    }
651    else
652    {
653  11 unredirectStreams();
654  11 updateConsole = false;
655    }
656    }
657   
 
658  0 toggle public Rectangle getBounds()
659    {
660  0 if (frame != null)
661    {
662  0 return frame.getBounds();
663    }
664  0 return null;
665    }
666   
667    /**
668    * set the banner that appears at the top of the console output
669    *
670    * @param string
671    */
 
672  11 toggle public void setHeader(String string)
673    {
674  11 header = string;
675  11 if (header.charAt(header.length() - 1) != '\n')
676    {
677  11 header += "\n";
678    }
679  11 textArea.insert(header, 0);
680    }
681   
682    /**
683    * get the banner
684    *
685    * @return
686    */
 
687  0 toggle public String getHeader()
688    {
689  0 return header;
690    }
691    }