Clover icon

Coverage Report

  1. Project Clover database Mon Sep 2 2024 17:57:51 BST
  2. Package jalview.gui

File Console.java

 

Coverage histogram

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

Code metrics

98
305
33
1
923
715
110
0.36
9.24
33
3.33

Classes

Class Line # Actions
Console 73 305 110
0.529816553%
 

Contributing tests

This file is covered by 246 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 java.awt.BorderLayout;
24    import java.awt.Color;
25    import java.awt.Dimension;
26    import java.awt.GraphicsEnvironment;
27    import java.awt.GridBagConstraints;
28    import java.awt.GridBagLayout;
29    import java.awt.Rectangle;
30    import java.awt.Toolkit;
31    import java.awt.datatransfer.Clipboard;
32    import java.awt.datatransfer.StringSelection;
33    import java.awt.event.ActionEvent;
34    import java.awt.event.ActionListener;
35    import java.awt.event.MouseAdapter;
36    import java.awt.event.MouseEvent;
37    import java.awt.event.WindowAdapter;
38    import java.awt.event.WindowEvent;
39    import java.awt.event.WindowListener;
40    import java.io.IOException;
41    import java.io.PipedInputStream;
42    import java.io.PipedOutputStream;
43    import java.io.PrintStream;
44   
45    import javax.swing.BorderFactory;
46    import javax.swing.JButton;
47    import javax.swing.JComboBox;
48    import javax.swing.JFrame;
49    import javax.swing.JLabel;
50    import javax.swing.JPanel;
51    import javax.swing.JScrollPane;
52    import javax.swing.JTextArea;
53    import javax.swing.SwingUtilities;
54    import javax.swing.border.Border;
55    import javax.swing.text.DefaultCaret;
56   
57    import jalview.log.JLoggerI.LogLevel;
58    import jalview.log.JLoggerLog4j;
59    import jalview.log.JalviewAppender;
60    import jalview.util.ChannelProperties;
61    import jalview.util.MessageManager;
62    import jalview.util.Platform;
63   
64    /**
65    * Simple Jalview Java Console. Version 1 - allows viewing of console output
66    * after desktop is created. Acquired with thanks from RJHM's site
67    * http://www.comweb.nl/java/Console/Console.html A simple Java Console for your
68    * application (Swing version) Requires Java 1.1.5 or higher Disclaimer the use
69    * of this source is at your own risk. Permision to use and distribute into your
70    * own applications RJHM van den Bergh , rvdb@comweb.nl
71    */
72   
 
73    public class Console extends WindowAdapter
74    implements WindowListener, ActionListener, Runnable
75    {
76    private JFrame frame;
77   
78    private JTextArea textArea;
79   
80    /*
81    * unused - tally and limit for lines in console window int lines = 0;
82    *
83    * int lim = 1000;
84    */
85    int byteslim = 102400, bytescut = 76800; // 100k and 75k cut point.
86   
87    private Thread reader, reader2, textAppender;
88   
89    private boolean quit;
90   
91    private final PrintStream stdout = System.out, stderr = System.err;
92   
93    private PipedInputStream pin = new PipedInputStream();
94   
95    private PipedInputStream pin2 = new PipedInputStream();
96   
97    private StringBuffer displayPipe = new StringBuffer();
98   
99    Thread errorThrower; // just for testing (Throws an Exception at this Console
100   
101    // are we attached to some parent Desktop
102    Desktop parent = null;
103   
104    private int MIN_WIDTH = 300;
105   
106    private int MIN_HEIGHT = 250;
107   
108    private JComboBox<LogLevel> logLevelCombo = new JComboBox<LogLevel>();
109   
110    protected LogLevel startingLogLevel = null;
111   
 
112  0 toggle public Console()
113    {
114    // create all components and add them
115  0 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
116  0 frame = initFrame("Java Console", screenSize.width / 2,
117    screenSize.height / 2, -1, -1);
118  0 frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
119  0 initConsole(true);
120    }
121   
 
122  75 toggle private void initConsole(boolean visible)
123    {
124  75 initConsole(visible, true);
125    }
126   
127    /**
128    *
129    * @param visible
130    * - open the window
131    * @param redirect
132    * - redirect std*
133    */
 
134  75 toggle private void initConsole(boolean visible, boolean redirect)
135    {
136    // CutAndPasteTransfer cpt = new CutAndPasteTransfer();
137    // textArea = cpt.getTextArea();
138  75 textArea = new JTextArea();
139  75 textArea.setEditable(false);
140    // autoscroll
141  75 DefaultCaret caret = (DefaultCaret) textArea.getCaret();
142  75 caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
143    // toggle autoscroll by clicking on the text area
144  75 Border pausedBorder = BorderFactory.createMatteBorder(2, 2, 2, 2,
145    textArea.getForeground());
146  75 Border noBorder = BorderFactory.createEmptyBorder(2, 2, 2, 2);
147  75 JScrollPane scrollPane = new JScrollPane(textArea);
148  75 scrollPane.setBorder(noBorder);
149  75 textArea.addMouseListener(new MouseAdapter()
150    {
 
151  0 toggle @Override
152    public void mouseClicked(MouseEvent e)
153    {
154  0 if (e.getButton() == MouseEvent.BUTTON1)
155    {
156  0 if (caret.getUpdatePolicy() == DefaultCaret.ALWAYS_UPDATE)
157    {
158  0 caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
159  0 scrollPane.setBorder(pausedBorder);
160    }
161    else
162    {
163  0 caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
164  0 textArea.setCaretPosition(textArea.getDocument().getLength());
165  0 scrollPane.setBorder(noBorder);
166    }
167    }
168    }
169    });
170   
171  75 JButton clearButton = new JButton(
172    MessageManager.getString("action.clear"));
173  75 JButton copyToClipboardButton = new JButton(
174    MessageManager.getString("label.copy_to_clipboard"));
175  75 copyToClipboardButton.addActionListener(new ActionListener()
176    {
 
177  0 toggle @Override
178    public void actionPerformed(ActionEvent e)
179    {
180  0 copyConsoleTextToClipboard();
181    }
182    });
183  75 copyToClipboardButton.addMouseListener(new MouseAdapter()
184    {
185    private Color bg = textArea.getBackground();
186   
187    private Color fg = textArea.getForeground();
188   
 
189  0 toggle @Override
190    public void mousePressed(MouseEvent e)
191    {
192  0 textArea.setBackground(textArea.getSelectionColor());
193  0 textArea.setForeground(textArea.getSelectedTextColor());
194    }
195   
 
196  0 toggle @Override
197    public void mouseReleased(MouseEvent e)
198    {
199  0 textArea.setBackground(bg);
200  0 textArea.setForeground(fg);
201    }
202   
203    });
204  75 copyToClipboardButton.setToolTipText(
205    MessageManager.getString("label.copy_to_clipboard_tooltip"));
206   
207  75 JLabel logLevelLabel = new JLabel(
208    MessageManager.getString("label.log_level") + ":");
209   
210    // logLevelCombo.addItem(LogLevel.ALL);
211  75 logLevelCombo.addItem(LogLevel.TRACE);
212  75 logLevelCombo.addItem(LogLevel.DEBUG);
213  75 logLevelCombo.addItem(LogLevel.INFO);
214  75 logLevelCombo.addItem(LogLevel.WARN);
215    // logLevelCombo.addItem(LogLevel.ERROR);
216    // logLevelCombo.addItem(LogLevel.FATAL);
217    // logLevelCombo.addItem(LogLevel.ERROR);
218    // logLevelCombo.addItem(LogLevel.OFF);
219    // set startingLogLevel
220   
221  75 if (jalview.bin.Console.getLogger() == null)
222    {
223  0 startingLogLevel = jalview.bin.Console.getCachedLogLevel();
224    }
225    else
226    {
227  75 startingLogLevel = jalview.bin.Console.getLogger().getLevel();
228    }
229  75 setChosenLogLevelCombo();
230  75 logLevelCombo.addActionListener(new ActionListener()
231    {
 
232  0 toggle @Override
233    public void actionPerformed(ActionEvent e)
234    {
235  0 if (jalview.bin.Console.log != null)
236    {
237  0 jalview.bin.Console.log
238    .setLevel((LogLevel) logLevelCombo.getSelectedItem());
239    }
240    }
241   
242    });
243   
244    // frame = cpt;
245  75 frame.getContentPane().setLayout(new BorderLayout());
246  75 frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
247  75 JPanel southPanel = new JPanel();
248  75 southPanel.setLayout(new GridBagLayout());
249   
250  75 JPanel logLevelPanel = new JPanel();
251  75 logLevelPanel.setAlignmentX(JPanel.LEFT_ALIGNMENT);
252  75 logLevelPanel.add(logLevelLabel);
253  75 logLevelPanel.add(logLevelCombo);
254  75 String logLevelTooltip = MessageManager.formatMessage(
255    "label.log_level_tooltip", startingLogLevel.toString());
256  75 logLevelLabel.setToolTipText(logLevelTooltip);
257  75 logLevelCombo.setToolTipText(logLevelTooltip);
258   
259  75 GridBagConstraints gbc = new GridBagConstraints();
260  75 gbc.gridx = 0;
261  75 gbc.gridy = 0;
262  75 gbc.gridwidth = 1;
263  75 gbc.gridheight = 1;
264  75 gbc.weightx = 0.1;
265  75 southPanel.add(logLevelPanel, gbc);
266   
267  75 gbc.gridx++;
268  75 gbc.weightx = 0.8;
269  75 gbc.fill = GridBagConstraints.HORIZONTAL;
270  75 southPanel.add(clearButton, gbc);
271   
272  75 gbc.gridx++;
273  75 gbc.weightx = 0.1;
274  75 gbc.fill = GridBagConstraints.NONE;
275  75 southPanel.add(copyToClipboardButton, gbc);
276   
277  75 southPanel.setVisible(true);
278  75 frame.getContentPane().add(southPanel, BorderLayout.SOUTH);
279  75 frame.setVisible(visible);
280  75 updateConsole = visible;
281  75 frame.addWindowListener(this);
282  75 clearButton.addActionListener(this);
283   
284  75 if (redirect)
285    {
286  75 redirectStreams();
287    }
288    else
289    {
290  0 unredirectStreams();
291    }
292  75 quit = false; // signals the Threads that they should exit
293   
294    // Starting two seperate threads to read from the PipedInputStreams
295    //
296  75 reader = new Thread(this);
297  75 reader.setDaemon(true);
298  75 reader.start();
299    //
300  75 reader2 = new Thread(this);
301  75 reader2.setDaemon(true);
302  75 reader2.start();
303    // and a thread to append text to the textarea
304  75 textAppender = new Thread(this);
305  75 textAppender.setDaemon(true);
306  75 textAppender.start();
307   
308    // set icons
309  75 frame.setIconImages(ChannelProperties.getIconList());
310    }
311   
 
312  75 toggle private void setChosenLogLevelCombo()
313    {
314  75 setChosenLogLevelCombo(startingLogLevel);
315    }
316   
 
317  75 toggle private void setChosenLogLevelCombo(LogLevel setLogLevel)
318    {
319  75 logLevelCombo.setSelectedItem(setLogLevel);
320  75 if (!logLevelCombo.getSelectedItem().equals(setLogLevel))
321    {
322    // setLogLevel not (yet) in list
323  0 if (setLogLevel != null && setLogLevel instanceof LogLevel)
324    {
325    // add new item to list (might be set via .jalview_properties)
326  0 boolean added = false;
327  0 for (int i = 0; i < logLevelCombo.getItemCount(); i++)
328    {
329  0 LogLevel l = logLevelCombo.getItemAt(i);
330  0 if (l.compareTo(setLogLevel) >= 0)
331    {
332  0 logLevelCombo.insertItemAt(setLogLevel, i);
333  0 added = true;
334  0 break;
335    }
336    }
337  0 if (!added) // lower priority than others or some confusion -- add to
338    // end of list
339    {
340  0 logLevelCombo.addItem(setLogLevel);
341    }
342  0 logLevelCombo.setSelectedItem(setLogLevel);
343    }
344    else
345    {
346  0 logLevelCombo.setSelectedItem(LogLevel.INFO);
347    }
348    }
349    }
350   
 
351  0 toggle private void copyConsoleTextToClipboard()
352    {
353  0 String consoleText = textArea.getText();
354  0 StringSelection consoleTextSelection = new StringSelection(consoleText);
355  0 Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
356  0 cb.setContents(consoleTextSelection, null);
357    }
358   
359    PipedOutputStream pout = null, perr = null;
360   
 
361  75 toggle public void redirectStreams()
362    {
363  75 if (pout == null)
364    {
365  75 try
366    {
367  75 pout = new PipedOutputStream(this.pin);
368  75 System.setOut(new PrintStream(pout, true));
369    } catch (java.io.IOException io)
370    {
371  0 textArea.append("Couldn't redirect STDOUT to this console\n"
372    + io.getMessage());
373  0 io.printStackTrace(stderr);
374    } catch (SecurityException se)
375    {
376  0 textArea.append("Couldn't redirect STDOUT to this console\n"
377    + se.getMessage());
378  0 se.printStackTrace(stderr);
379    }
380   
381  75 try
382    {
383  75 perr = new PipedOutputStream(this.pin2);
384  75 System.setErr(new PrintStream(perr, true));
385    } catch (java.io.IOException io)
386    {
387  0 textArea.append("Couldn't redirect STDERR to this console\n"
388    + io.getMessage());
389  0 io.printStackTrace(stderr);
390    } catch (SecurityException se)
391    {
392  0 textArea.append("Couldn't redirect STDERR to this console\n"
393    + se.getMessage());
394  0 se.printStackTrace(stderr);
395    }
396    }
397    }
398   
 
399  75 toggle public void unredirectStreams()
400    {
401  75 if (pout != null)
402    {
403  75 try
404    {
405  75 System.setOut(stdout);
406  75 pout.flush();
407  75 pout.close();
408  75 pin = new PipedInputStream();
409  75 pout = null;
410    } catch (java.io.IOException io)
411    {
412  0 textArea.append("Couldn't unredirect STDOUT to this console\n"
413    + io.getMessage());
414  0 io.printStackTrace(stderr);
415    } catch (SecurityException se)
416    {
417  0 textArea.append("Couldn't unredirect STDOUT to this console\n"
418    + se.getMessage());
419  0 se.printStackTrace(stderr);
420    }
421   
422  75 try
423    {
424  75 System.setErr(stderr);
425  75 perr.flush();
426  75 perr.close();
427  75 pin2 = new PipedInputStream();
428  75 perr = null;
429    } catch (java.io.IOException io)
430    {
431  0 textArea.append("Couldn't unredirect STDERR to this console\n"
432    + io.getMessage());
433  0 io.printStackTrace(stderr);
434    } catch (SecurityException se)
435    {
436  0 textArea.append("Couldn't unredirect STDERR to this console\n"
437    + se.getMessage());
438  0 se.printStackTrace(stderr);
439    }
440    }
441    }
442   
 
443  0 toggle public void test()
444    {
445    // testing part
446    // you may omit this part for your application
447    //
448   
449  0 jalview.bin.Console.outPrintln("Hello World 2");
450  0 jalview.bin.Console.outPrintln("All fonts available to Graphic2D:\n");
451  0 GraphicsEnvironment ge = GraphicsEnvironment
452    .getLocalGraphicsEnvironment();
453  0 String[] fontNames = ge.getAvailableFontFamilyNames();
454  0 for (int n = 0; n < fontNames.length; n++)
455    {
456  0 jalview.bin.Console.outPrintln(fontNames[n]);
457    }
458    // Testing part: simple an error thrown anywhere in this JVM will be printed
459    // on the Console
460    // We do it with a seperate Thread becasue we don't wan't to break a Thread
461    // used by the Console.
462  0 jalview.bin.Console.outPrintln("\nLets throw an error on this console");
463  0 errorThrower = new Thread(this);
464  0 errorThrower.setDaemon(true);
465  0 errorThrower.start();
466    }
467   
 
468  75 toggle private JFrame initFrame(String string, int i, int j, int x, int y)
469    {
470  75 JFrame frame = new JFrame(string);
471  75 frame.setName(string);
472  75 if (x == -1)
473    {
474  0 x = i / 2;
475    }
476  75 if (y == -1)
477    {
478  0 y = j / 2;
479    }
480  75 frame.setBounds(x, y, i, j);
481  75 return frame;
482    }
483   
484    /**
485    * attach a console to the desktop - the desktop will open it if requested.
486    *
487    * @param desktop
488    */
 
489  75 toggle public Console(Desktop desktop)
490    {
491  75 parent = desktop;
492    // window name - get x,y,width, height possibly scaled
493  75 Rectangle bounds = parent == null ? null
494    : parent.getLastKnownDimensions("JAVA_CONSOLE_");
495  75 if (bounds != null)
496    {
497  59 frame = initFrame(
498    ChannelProperties.getProperty("app_name") + " Java Console",
499    bounds.width, bounds.height, bounds.x, bounds.y);
500    }
501  16 else if (parent != null && parent.getWidth() > 0
502    && parent.getHeight() > 0)
503    {
504  0 frame = initFrame(
505    ChannelProperties.getProperty("app_name") + " Java Console",
506    parent.getWidth() / 2, parent.getHeight() / 4, parent.getX(),
507    parent.getY());
508    }
509    else
510    {
511  16 frame = initFrame(
512    ChannelProperties.getProperty("app_name") + " Java Console",
513    MIN_WIDTH, MIN_HEIGHT, 10, 10);
514    }
515  75 frame.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
516    // parent.add(frame);
517  75 initConsole(false);
518  75 LogLevel level = (LogLevel) logLevelCombo.getSelectedItem();
519  75 if (!Platform.isJS())
520    {
521  75 JalviewAppender jappender = new JalviewAppender(level);
522  75 JalviewAppender.setTextArea(textArea);
523  75 jappender.start();
524  75 if (jalview.bin.Console.log != null
525    && jalview.bin.Console.log instanceof JLoggerLog4j)
526    {
527  75 JLoggerLog4j.addAppender(jalview.bin.Console.log, jappender);
528    }
529    }
530    }
531   
 
532  81 toggle public synchronized void stopConsole()
533    {
534  81 quit = true;
535  81 this.notifyAll();
536    /*
537    * reader.notify(); reader2.notify(); if (errorThrower!=null)
538    * errorThrower.notify(); // stop all threads if (textAppender!=null)
539    * textAppender.notify();
540    */
541  81 if (pout != null)
542    {
543  0 try
544    {
545  0 reader.join(10);
546  0 pin.close();
547    } catch (Exception e)
548    {
549  0 jalview.bin.Console.debug("pin.close() error", e);
550    }
551  0 try
552    {
553  0 reader2.join(10);
554  0 pin2.close();
555    } catch (Exception e)
556    {
557  0 jalview.bin.Console.debug("pin2.close() error", e);
558    }
559  0 try
560    {
561  0 textAppender.join(10);
562    } catch (Exception e)
563    {
564  0 jalview.bin.Console.debug("textAppender.join(10) error", e);
565    }
566    }
567    /*
568    if (!frame.isVisible())
569    {
570    frame.dispose();
571    }
572    */
573    // System.exit(0);
574    }
575   
 
576  0 toggle @Override
577    public synchronized void windowClosed(WindowEvent evt)
578    {
579  0 frame.setVisible(false);
580  0 closeConsoleGui();
581    }
582   
 
583  0 toggle private void closeConsoleGui()
584    {
585  0 updateConsole = false;
586  0 if (parent == null)
587    {
588   
589  0 stopConsole();
590    }
591    else
592    {
593  0 parent.showConsole(false);
594    }
595    }
596   
 
597  0 toggle @Override
598    public synchronized void windowClosing(WindowEvent evt)
599    {
600  0 frame.setVisible(false); // default behaviour of JFrame
601  0 closeConsoleGui();
602   
603    // frame.dispose();
604    }
605   
 
606  0 toggle @Override
607    public synchronized void actionPerformed(ActionEvent evt)
608    {
609  0 trimBuffer(true);
610    // textArea.setText("");
611    }
612   
 
613  225 toggle @Override
614    public synchronized void run()
615    {
616  225 try
617    {
618  45954 while (Thread.currentThread() == reader)
619    {
620  45804 if (pin == null || pin.available() == 0)
621    {
622  45816 try
623    {
624  45814 this.wait(100);
625    } catch (InterruptedException ie)
626    {
627  0 jalview.bin.Console.debug("pin.available() error", ie);
628    }
629    }
630   
631  45767 while (pin.available() != 0)
632    {
633  3 String input = this.readLine(pin);
634  3 stdout.print(input);
635  3 long time = System.nanoTime();
636  3 appendToTextArea(input);
637    // stderr.println("Time taken to stdout append:\t"
638    // + (System.nanoTime() - time) + " ns");
639    // lines++;
640    }
641  45786 if (quit)
642    {
643  38 return;
644    }
645    }
646   
647  45895 while (Thread.currentThread() == reader2)
648    {
649  45805 if (pin2.available() == 0)
650    {
651  45834 try
652    {
653  45821 this.wait(100); // ##### implicated BLOCKED
654  45780 if (pin2.available() == 0)
655    {
656  45793 trimBuffer(false);
657    }
658    } catch (InterruptedException ie)
659    {
660  0 jalview.bin.Console.debug("pin.available() error", ie);
661    }
662    }
663  45780 while (pin2.available() != 0)
664    {
665  0 String input = this.readLine(pin2);
666  0 stderr.print(input);
667  0 long time = System.nanoTime();
668  0 appendToTextArea(input);
669    // stderr.println("Time taken to stderr append:\t"
670    // + (System.nanoTime() - time) + " ns");
671    // lines++;
672    }
673  45789 if (quit)
674    {
675  38 return;
676    }
677    }
678  45833 while (Thread.currentThread() == textAppender)
679    {
680  45843 if (updateConsole)
681    {
682    // check string buffer - if greater than console, clear console and
683    // replace with last segment of content, otherwise, append all to
684    // content.
685  0 while (displayPipe.length() > 0)
686    {
687  0 StringBuffer tmp = new StringBuffer(), replace;
688  0 synchronized (displayPipe)
689    {
690  0 replace = displayPipe;
691  0 displayPipe = tmp;
692    }
693    // Append formatted message to textarea using the Swing Thread.
694  0 SwingUtilities.invokeLater(new Runnable()
695    {
 
696  0 toggle public void run()
697    {
698  0 textArea.append(replace.toString());
699  0 trimBuffer(false);
700    }
701    });
702    }
703  0 if (displayPipe.length() == 0)
704    {
705  0 try
706    {
707  0 this.wait(100);
708  0 if (displayPipe.length() == 0)
709    {
710    // post a trim on Swing Thread.
711  0 SwingUtilities.invokeLater(new Runnable()
712    {
 
713  0 toggle public void run()
714    {
715  0 trimBuffer(false);
716    }
717    });
718    }
719    } catch (InterruptedException e)
720    {
721  0 jalview.bin.Console.debug("displayPipe.length() error", e);
722    }
723    }
724    }
725    else
726    {
727  45837 try
728    {
729  45852 this.wait(100);
730    } catch (InterruptedException e)
731    {
732  0 jalview.bin.Console.debug("this.wait(100) error", e);
733    }
734    }
735  45778 if (quit)
736    {
737  38 return;
738    }
739   
740    }
741    } catch (Exception e)
742    {
743  0 textArea.append("\nConsole reports an Internal error.");
744  0 textArea.append("The error is: " + e.getMessage());
745    // Need to uncomment this to ensure that line tally is synched.
746    // lines += 2;
747  0 stderr.println(
748    "Console reports an Internal error.\nThe error is: " + e);
749    }
750   
751    // just for testing (Throw a Nullpointer after 1 second)
752  0 if (Thread.currentThread() == errorThrower)
753    {
754  0 try
755    {
756  0 this.wait(1000);
757    } catch (InterruptedException ie)
758    {
759  0 jalview.bin.Console.debug("this.wait(1000) error", ie);
760    }
761  0 throw new NullPointerException(
762    MessageManager.getString("exception.application_test_npe"));
763    }
764    }
765   
 
766  3 toggle private void appendToTextArea(final String input)
767    {
768  3 if (updateConsole == false)
769    {
770    // do nothing;
771  3 return;
772    }
773  0 long time = System.nanoTime();
774  0 javax.swing.SwingUtilities.invokeLater(new Runnable()
775    {
 
776  0 toggle @Override
777    public void run()
778    {
779  0 displayPipe.append(input);
780    }
781    });
782    // stderr.println("Time taken to Spawnappend:\t" + (System.nanoTime() -
783    // time)
784    // + " ns");
785    }
786   
787    private String header = null;
788   
789    private boolean updateConsole = false;
790   
 
791  45741 toggle private synchronized void trimBuffer(boolean clear)
792    {
793  45766 if (header == null && textArea.getLineCount() > 5)
794    {
795  0 try
796    {
797  0 header = textArea.getText(0, textArea.getLineStartOffset(5))
798    + "\nTruncated...\n";
799    } catch (Exception e)
800    {
801  0 jalview.bin.Console.warn("textArea Exception", e);
802    }
803    }
804    // trim the buffer
805  45775 int tlength = textArea.getDocument().getLength();
806  45785 if (header != null)
807    {
808  45783 if (clear || (tlength > byteslim))
809    {
810  0 try
811    {
812  0 if (!clear)
813    {
814  0 long time = System.nanoTime();
815  0 textArea.replaceRange(header, 0, tlength - bytescut);
816    // stderr.println("Time taken to cut:\t"
817    // + (System.nanoTime() - time) + " ns");
818    }
819    else
820    {
821  0 textArea.setText(header);
822    }
823    } catch (Exception e)
824    {
825  0 jalview.bin.Console.warn("textArea Exception", e);
826    }
827    // lines = textArea.getLineCount();
828    }
829    }
830   
831    }
832   
 
833  3 toggle public synchronized String readLine(PipedInputStream in)
834    throws IOException
835    {
836  3 String input = "";
837  3 int lp = -1;
838  3 do
839    {
840  5 int available = in.available();
841  5 if (available == 0)
842    {
843  2 break;
844    }
845  3 byte b[] = new byte[available];
846  3 in.read(b);
847  3 input = input + new String(b, 0, b.length);
848    // counts lines - we don't do this for speed.
849    // while ((lp = input.indexOf("\n", lp + 1)) > -1)
850    // {
851    // lines++;
852    // }
853  3 } while (!input.endsWith("\n") && !input.endsWith("\r\n") && !quit);
854  3 return input;
855    }
856   
857    /**
858    * @j2sIgnore
859    * @param arg
860    */
 
861  0 toggle public static void main(String[] arg)
862    {
863  0 new Console().test(); // create console with not reference
864   
865    }
866   
 
867  75 toggle public void setVisible(boolean selected)
868    {
869  75 frame.setVisible(selected);
870  75 if (selected == true)
871    {
872  0 setChosenLogLevelCombo();
873  0 redirectStreams();
874  0 updateConsole = true;
875  0 frame.toFront();
876    }
877    else
878    {
879    // reset log level to what it was before
880  75 if (jalview.bin.Console.log != null)
881    {
882  75 jalview.bin.Console.log.setLevel(startingLogLevel);
883    }
884   
885  75 unredirectStreams();
886  75 updateConsole = false;
887    }
888    }
889   
 
890  81 toggle public Rectangle getBounds()
891    {
892  81 if (frame != null)
893    {
894  81 return frame.getBounds();
895    }
896  0 return null;
897    }
898   
899    /**
900    * set the banner that appears at the top of the console output
901    *
902    * @param string
903    */
 
904  75 toggle public void setHeader(String string)
905    {
906  75 header = string;
907  75 if (header.charAt(header.length() - 1) != '\n')
908    {
909  0 header += "\n";
910    }
911  75 textArea.insert(header, 0);
912    }
913   
914    /**
915    * get the banner
916    *
917    * @return
918    */
 
919  0 toggle public String getHeader()
920    {
921  0 return header;
922    }
923    }