Clover icon

Coverage Report

  1. Project Clover database Thu Aug 13 2020 12:04:21 BST
  2. Package jalview.gui

File Console.java

 

Coverage histogram

../../img/srcFileCovDistChart6.png
33% of files have more coverage

Code metrics

76
215
24
1
694
516
86
0.4
8.96
24
3.58

Classes

Class Line # Actions
Console 56 215 86
0.5301587653%
 

Contributing tests

This file is covered by 136 tests. .

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  18 toggle private void initConsole(boolean visible)
101    {
102  18 initConsole(visible, true);
103    }
104   
105    /**
106    *
107    * @param visible
108    * - open the window
109    * @param redirect
110    * - redirect std*
111    */
 
112  18 toggle private void initConsole(boolean visible, boolean redirect)
113    {
114    // CutAndPasteTransfer cpt = new CutAndPasteTransfer();
115    // textArea = cpt.getTextArea();
116  18 textArea = new JTextArea();
117  18 textArea.setEditable(false);
118  18 JButton button = new JButton(MessageManager.getString("action.clear"));
119   
120    // frame = cpt;
121  18 frame.getContentPane().setLayout(new BorderLayout());
122  18 frame.getContentPane().add(new JScrollPane(textArea),
123    BorderLayout.CENTER);
124  18 frame.getContentPane().add(button, BorderLayout.SOUTH);
125  18 frame.setVisible(visible);
126  18 updateConsole = visible;
127  18 frame.addWindowListener(this);
128  18 button.addActionListener(this);
129  18 if (redirect)
130    {
131  18 redirectStreams();
132    }
133    else
134    {
135  0 unredirectStreams();
136    }
137  18 quit = false; // signals the Threads that they should exit
138   
139    // Starting two seperate threads to read from the PipedInputStreams
140    //
141  18 reader = new Thread(this);
142  18 reader.setDaemon(true);
143  18 reader.start();
144    //
145  18 reader2 = new Thread(this);
146  18 reader2.setDaemon(true);
147  18 reader2.start();
148    // and a thread to append text to the textarea
149  18 textAppender = new Thread(this);
150  18 textAppender.setDaemon(true);
151  18 textAppender.start();
152    }
153   
154    PipedOutputStream pout = null, perr = null;
155   
 
156  18 toggle public void redirectStreams()
157    {
158  18 if (pout == null)
159    {
160  18 try
161    {
162  18 pout = new PipedOutputStream(this.pin);
163  18 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  18 try
177    {
178  18 perr = new PipedOutputStream(this.pin2);
179  18 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  18 toggle public void unredirectStreams()
195    {
196  18 if (pout != null)
197    {
198  18 try
199    {
200  18 System.setOut(stdout);
201  18 pout.flush();
202  18 pout.close();
203  18 pin = new PipedInputStream();
204  18 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  18 try
218    {
219  18 System.setErr(stderr);
220  18 perr.flush();
221  18 perr.close();
222  18 pin2 = new PipedInputStream();
223  18 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  18 toggle private JFrame initFrame(String string, int i, int j, int x, int y)
264    {
265  18 JFrame frame = new JFrame(string);
266  18 frame.setName(string);
267  18 if (x == -1)
268    {
269  0 x = i / 2;
270    }
271  18 if (y == -1)
272    {
273  0 y = j / 2;
274    }
275  18 frame.setBounds(x, y, i, j);
276  18 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  18 toggle public Console(Desktop desktop, boolean showjconsole)
297    {
298  18 parent = desktop;
299    // window name - get x,y,width, height possibly scaled
300  18 Rectangle bounds = desktop.getLastKnownDimensions("JAVA_CONSOLE_");
301  18 if (bounds == null)
302    {
303  1 frame = initFrame("Jalview Java Console", desktop.getWidth() / 2,
304    desktop.getHeight() / 4, desktop.getX(), desktop.getY());
305    }
306    else
307    {
308  17 frame = initFrame("Jalview Java Console", bounds.width, bounds.height,
309    bounds.x, bounds.y);
310    }
311  18 frame.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
312    // desktop.add(frame);
313  18 initConsole(false);
314  18 JalviewAppender jappender = new JalviewAppender();
315  18 jappender.setLayout(new SimpleLayout());
316  18 JalviewAppender.setTextArea(textArea);
317  18 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  54 toggle @Override
397    public synchronized void run()
398    {
399  54 try
400    {
401  3314 while (Thread.currentThread() == reader)
402    {
403  3278 if (pin == null || pin.available() == 0)
404    {
405  3276 try
406    {
407  3276 this.wait(100);
408  3258 if (pin.available() == 0)
409    {
410  3257 trimBuffer(false);
411    }
412    } catch (InterruptedException ie)
413    {
414    }
415    }
416   
417  3262 while (pin.available() != 0)
418    {
419  2 String input = this.readLine(pin);
420  2 stdout.print(input);
421  2 long time = System.nanoTime();
422  2 appendToTextArea(input);
423    // stderr.println("Time taken to stdout append:\t"
424    // + (System.nanoTime() - time) + " ns");
425    // lines++;
426    }
427  3260 if (quit)
428    {
429  0 return;
430    }
431    }
432   
433  3286 while (Thread.currentThread() == reader2)
434    {
435  3268 if (pin2.available() == 0)
436    {
437  3266 try
438    {
439  3265 this.wait(100);
440  3247 if (pin2.available() == 0)
441    {
442  3247 trimBuffer(false);
443    }
444    } catch (InterruptedException ie)
445    {
446    }
447    }
448  3252 while (pin2.available() != 0)
449    {
450  2 String input = this.readLine(pin2);
451  2 stderr.print(input);
452  2 long time = System.nanoTime();
453  2 appendToTextArea(input);
454    // stderr.println("Time taken to stderr append:\t"
455    // + (System.nanoTime() - time) + " ns");
456    // lines++;
457    }
458  3249 if (quit)
459    {
460  0 return;
461    }
462    }
463  3268 while (Thread.currentThread() == textAppender)
464    {
465  3268 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    }
501    }
502    else
503    {
504  3268 try
505    {
506  3268 this.wait(100);
507    } catch (InterruptedException e)
508    {
509   
510    }
511    }
512  3250 if (quit)
513    {
514  0 return;
515    }
516   
517    }
518    } catch (Exception e)
519    {
520  0 textArea.append("\nConsole reports an Internal error.");
521  0 textArea.append("The error is: " + e.getMessage());
522    // Need to uncomment this to ensure that line tally is synched.
523    // lines += 2;
524  0 stderr.println(
525    "Console reports an Internal error.\nThe error is: " + e);
526    }
527   
528    // just for testing (Throw a Nullpointer after 1 second)
529  0 if (Thread.currentThread() == errorThrower)
530    {
531  0 try
532    {
533  0 this.wait(1000);
534    } catch (InterruptedException ie)
535    {
536    }
537  0 throw new NullPointerException(
538    MessageManager.getString("exception.application_test_npe"));
539    }
540    }
541   
 
542  4 toggle private void appendToTextArea(final String input)
543    {
544  4 if (updateConsole == false)
545    {
546    // do nothing;
547  4 return;
548    }
549  0 long time = System.nanoTime();
550  0 javax.swing.SwingUtilities.invokeLater(new Runnable()
551    {
 
552  0 toggle @Override
553    public void run()
554    {
555  0 displayPipe.append(input); // change to stringBuffer
556    // displayPipe.flush();
557   
558    }
559    });
560    // stderr.println("Time taken to Spawnappend:\t" + (System.nanoTime() -
561    // time)
562    // + " ns");
563    }
564   
565    private String header = null;
566   
567    private boolean updateConsole = false;
568   
 
569  6493 toggle private synchronized void trimBuffer(boolean clear)
570    {
571  6494 if (header == null && textArea.getLineCount() > 5)
572    {
573  0 try
574    {
575  0 header = textArea.getText(0, textArea.getLineStartOffset(5))
576    + "\nTruncated...\n";
577    } catch (Exception e)
578    {
579  0 e.printStackTrace();
580    }
581    }
582    // trim the buffer
583  6496 int tlength = textArea.getDocument().getLength();
584  6503 if (header != null)
585    {
586  6505 if (clear || (tlength > byteslim))
587    {
588  4 try
589    {
590  4 if (!clear)
591    {
592  4 long time = System.nanoTime();
593  4 textArea.replaceRange(header, 0, tlength - bytescut);
594    // stderr.println("Time taken to cut:\t"
595    // + (System.nanoTime() - time) + " ns");
596    }
597    else
598    {
599  0 textArea.setText(header);
600    }
601    } catch (Exception e)
602    {
603  0 e.printStackTrace();
604    }
605    // lines = textArea.getLineCount();
606    }
607    }
608   
609    }
610   
 
611  4 toggle public synchronized String readLine(PipedInputStream in)
612    throws IOException
613    {
614  4 String input = "";
615  4 int lp = -1;
616  4 do
617    {
618  5 int available = in.available();
619  5 if (available == 0)
620    {
621  1 break;
622    }
623  4 byte b[] = new byte[available];
624  4 in.read(b);
625  4 input = input + new String(b, 0, b.length);
626    // counts lines - we don't do this for speed.
627    // while ((lp = input.indexOf("\n", lp + 1)) > -1)
628    // {
629    // lines++;
630    // }
631  4 } while (!input.endsWith("\n") && !input.endsWith("\r\n") && !quit);
632  4 return input;
633    }
634   
635    /**
636    * @j2sIgnore
637    * @param arg
638    */
 
639  0 toggle public static void main(String[] arg)
640    {
641  0 new Console().test(); // create console with not reference
642   
643    }
644   
 
645  18 toggle public void setVisible(boolean selected)
646    {
647  18 frame.setVisible(selected);
648  18 if (selected == true)
649    {
650  0 redirectStreams();
651  0 updateConsole = true;
652  0 frame.toFront();
653    }
654    else
655    {
656  18 unredirectStreams();
657  18 updateConsole = false;
658    }
659    }
660   
 
661  0 toggle public Rectangle getBounds()
662    {
663  0 if (frame != null)
664    {
665  0 return frame.getBounds();
666    }
667  0 return null;
668    }
669   
670    /**
671    * set the banner that appears at the top of the console output
672    *
673    * @param string
674    */
 
675  18 toggle public void setHeader(String string)
676    {
677  18 header = string;
678  18 if (header.charAt(header.length() - 1) != '\n')
679    {
680  0 header += "\n";
681    }
682  18 textArea.insert(header, 0);
683    }
684   
685    /**
686    * get the banner
687    *
688    * @return
689    */
 
690  0 toggle public String getHeader()
691    {
692  0 return header;
693    }
694    }