prototype Java log window and sticky configuration
authorjprocter <Jim Procter>
Tue, 13 Oct 2009 15:22:19 +0000 (15:22 +0000)
committerjprocter <Jim Procter>
Tue, 13 Oct 2009 15:22:19 +0000 (15:22 +0000)
src/jalview/gui/Console.java [new file with mode: 0644]
src/jalview/gui/JalviewAppender.java [new file with mode: 0644]
src/jalview/jbgui/GDesktop.java

diff --git a/src/jalview/gui/Console.java b/src/jalview/gui/Console.java
new file mode 100644 (file)
index 0000000..57d563b
--- /dev/null
@@ -0,0 +1,326 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4.1)
+ * Copyright (C) 2009 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+package jalview.gui;
+
+import java.io.*;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+
+import org.apache.log4j.SimpleLayout;
+
+/**
+ * Simple Jalview Java Console. Version 1 - allows viewing of console output after desktop is created.
+ * Acquired with thanks from RJHM's site http://www.comweb.nl/java/Console/Console.html
+ *  A simple Java Console for your application (Swing version)
+ * Requires Java 1.1.5 or higher
+ * Disclaimer the use of this source is at your own risk. 
+ * Permision to use and distribute into your own applications
+ * RJHM van den Bergh , rvdb@comweb.nl
+ */
+
+public class Console extends WindowAdapter implements WindowListener,
+        ActionListener, Runnable
+{
+  private JFrame frame;
+
+  private JTextArea textArea;
+
+  private Thread reader;
+
+  private Thread reader2;
+
+  private boolean quit;
+
+  private final PipedInputStream pin = new PipedInputStream();
+
+  private final PipedInputStream pin2 = new PipedInputStream();
+
+
+  Thread errorThrower; // just for testing (Throws an Exception at this Console
+  // are we attached to some parent Desktop
+  Desktop parent = null;
+  public Console()
+  {
+    // create all components and add them
+    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+    frame = initFrame("Java Console", screenSize.width / 2,
+            screenSize.height / 2, -1, -1);
+    initConsole(true);
+  }
+
+  private void initConsole(boolean visible)
+  {
+    // CutAndPasteTransfer cpt = new CutAndPasteTransfer();
+    //textArea = cpt.getTextArea();
+    textArea = new JTextArea();
+    textArea.setEditable(false);
+    JButton button = new JButton("clear");
+
+    // frame = cpt;
+    frame.getContentPane().setLayout(new BorderLayout());
+    frame.getContentPane().add(new JScrollPane(textArea),
+            BorderLayout.CENTER);
+    frame.getContentPane().add(button, BorderLayout.SOUTH);
+    frame.setVisible(visible);
+
+    frame.addWindowListener(this);
+    button.addActionListener(this);
+
+    try
+    {
+      PipedOutputStream pout = new PipedOutputStream(this.pin);
+      System.setOut(new PrintStream(pout, true));
+    } catch (java.io.IOException io)
+    {
+      textArea.append("Couldn't redirect STDOUT to this console\n"
+              + io.getMessage());
+    } catch (SecurityException se)
+    {
+      textArea.append("Couldn't redirect STDOUT to this console\n"
+              + se.getMessage());
+    }
+
+    try
+    {
+      PipedOutputStream pout2 = new PipedOutputStream(this.pin2);
+      System.setErr(new PrintStream(pout2, true));
+    } catch (java.io.IOException io)
+    {
+      textArea.append("Couldn't redirect STDERR to this console\n"
+              + io.getMessage());
+    } catch (SecurityException se)
+    {
+      textArea.append("Couldn't redirect STDERR to this console\n"
+              + se.getMessage());
+    }
+
+    quit = false; // signals the Threads that they should exit
+
+    // Starting two seperate threads to read from the PipedInputStreams
+    //
+    reader = new Thread(this);
+    reader.setDaemon(true);
+    reader.start();
+    //
+    reader2 = new Thread(this);
+    reader2.setDaemon(true);
+    reader2.start();
+  }
+  public void test() {
+    // testing part
+    // you may omit this part for your application
+    // 
+    
+    System.out.println("Hello World 2");
+    System.out.println("All fonts available to Graphic2D:\n");
+    GraphicsEnvironment ge = GraphicsEnvironment
+            .getLocalGraphicsEnvironment();
+    String[] fontNames = ge.getAvailableFontFamilyNames();
+    for (int n = 0; n < fontNames.length; n++)
+      System.out.println(fontNames[n]);
+    // Testing part: simple an error thrown anywhere in this JVM will be printed
+    // on the Console
+    // We do it with a seperate Thread becasue we don't wan't to break a Thread
+    // used by the Console.
+    System.out.println("\nLets throw an error on this console");
+    errorThrower = new Thread(this);
+    errorThrower.setDaemon(true);
+    errorThrower.start();
+  }
+
+  private JFrame initFrame(String string, int i, int j, int x, int y)
+  {
+    JFrame frame = new JFrame(string);
+    frame.setName(string);
+    if (x==-1)
+      x = (int) (i / 2);
+    if (y==-1)
+      y = (int) (j / 2);
+    frame.setBounds(x, y, i, j);
+    return frame;
+  }
+
+  /**
+   * attach a console to the desktop - the desktop will open it if requested.
+   * 
+   * @param desktop
+   */
+  public Console(Desktop desktop)
+  {
+    parent = desktop;
+    // window name - get x,y,width, height possibly scaled
+    Rectangle bounds = desktop.getLastKnownDimensions("JAVA_CONSOLE_");
+    if (bounds==null)
+    {
+    frame = initFrame("Jalview Java Console", desktop.getWidth() / 2,
+            desktop.getHeight() / 4,desktop.getX(),desktop.getY());
+    } else {
+      frame = initFrame("Jalview Java Console", bounds.width, bounds.height, bounds.x, bounds.y);
+    }
+    // desktop.add(frame);
+    initConsole(false);
+    JalviewAppender jappender = new JalviewAppender();
+    jappender.setLayout(new SimpleLayout());
+    jappender.setTextArea(textArea);
+    org.apache.log4j.Logger.getRootLogger().addAppender(jappender);
+  }
+
+  public synchronized void stopConsole()
+  {
+    quit = true;
+    this.notifyAll(); // stop all threads
+    try
+    {
+      reader.join(10);
+      pin.close();
+    } catch (Exception e)
+    {
+    }
+    try
+    {
+      reader2.join(10);
+      pin2.close();
+    } catch (Exception e)
+    {
+    }
+//    System.exit(0);
+  }
+
+  public synchronized void windowClosed(WindowEvent evt)
+  {
+    frame.setVisible(false);
+    if (parent == null)
+    {
+
+      stopConsole();
+    } else {
+      parent.showConsole(false);
+    }
+  }
+
+  public synchronized void windowClosing(WindowEvent evt)
+  {
+    frame.setVisible(false); // default behaviour of JFrame
+//    frame.dispose();
+  }
+
+  public synchronized void actionPerformed(ActionEvent evt)
+  {
+    textArea.setText("");
+  }
+
+  public synchronized void run()
+  {
+    try
+    {
+      while (Thread.currentThread() == reader)
+      {
+        try
+        {
+          this.wait(100);
+        } catch (InterruptedException ie)
+        {
+        }
+        if (pin.available() != 0)
+        {
+          String input = this.readLine(pin);
+          textArea.append(input);
+        }
+        if (quit)
+          return;
+      }
+
+      while (Thread.currentThread() == reader2)
+      {
+        try
+        {
+          this.wait(100);
+        } catch (InterruptedException ie)
+        {
+        }
+        if (pin2.available() != 0)
+        {
+          String input = this.readLine(pin2);
+          textArea.append(input);
+        }
+        if (quit)
+          return;
+      }
+    } catch (Exception e)
+    {
+      textArea.append("\nConsole reports an Internal error.");
+      textArea.append("The error is: " + e);
+    }
+
+    // just for testing (Throw a Nullpointer after 1 second)
+    if (Thread.currentThread() == errorThrower)
+    {
+      try
+      {
+        this.wait(1000);
+      } catch (InterruptedException ie)
+      {
+      }
+      throw new NullPointerException(
+              "Application test: throwing an NullPointerException It should arrive at the console");
+    }
+
+  }
+
+  public synchronized String readLine(PipedInputStream in)
+          throws IOException
+  {
+    String input = "";
+    do
+    {
+      int available = in.available();
+      if (available == 0)
+        break;
+      byte b[] = new byte[available];
+      in.read(b);
+      input = input + new String(b, 0, b.length);
+    } while (!input.endsWith("\n") && !input.endsWith("\r\n") && !quit);
+    return input;
+  }
+
+  public static void main(String[] arg)
+  {
+    new Console().test(); // create console with not reference
+    
+  }
+
+  public void setVisible(boolean selected)
+  {
+    frame.setVisible(selected);
+    if (selected == true)
+    {
+      frame.toFront();
+    }    
+  }
+
+  public Rectangle getBounds()
+  {
+    if (frame!=null)
+    {
+      return frame.getBounds();
+    }
+    return null;
+  }
+}
diff --git a/src/jalview/gui/JalviewAppender.java b/src/jalview/gui/JalviewAppender.java
new file mode 100644 (file)
index 0000000..8d3f990
--- /dev/null
@@ -0,0 +1,39 @@
+package jalview.gui;
+
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+
+import org.apache.log4j.WriterAppender;
+import org.apache.log4j.spi.LoggingEvent;
+
+/**
+ * From http://textareaappender.zcage.com/
+ * the means to capture the logs, too.
+ * Simple example of creating a Log4j appender that will
+ * write to a JTextArea. 
+ */
+public class JalviewAppender extends WriterAppender {
+        
+        static private JTextArea jTextArea = null;
+        
+        /** Set the target JTextArea for the logging information to appear. */
+        static public void setTextArea(JTextArea jTextArea) {
+                JalviewAppender.jTextArea = jTextArea;
+        }
+        /**
+         * Format and then append the loggingEvent to the stored
+         * JTextArea.
+         */
+        public void append(LoggingEvent loggingEvent) {
+                final String message = this.layout.format(loggingEvent);
+
+                // Append formatted message to textarea using the Swing Thread.
+                SwingUtilities.invokeLater(new Runnable() {
+                        public void run() {
+                          if (jTextArea!=null) {
+                            jTextArea.append(message);
+                          }
+                        }
+                });
+        }
+}
\ No newline at end of file
index 5ff13af..773267d 100755 (executable)
@@ -87,6 +87,8 @@ public class GDesktop extends JFrame
 
   JMenuItem garbageCollect = new JMenuItem();
 
+  protected JCheckBoxMenuItem showConsole = new JCheckBoxMenuItem();
+  
   /**
    * Creates a new GDesktop object.
    */
@@ -297,6 +299,14 @@ public class GDesktop extends JFrame
         showMemusage_actionPerformed(e);
       }
     });
+    showConsole.setText("Show Java Console");
+    showConsole.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        showConsole_actionPerformed(e);
+      }
+    });
     desktopMenubar.add(FileMenu);
     desktopMenubar.add(toolsMenu);
     VamsasMenu.setVisible(false);
@@ -320,6 +330,7 @@ public class GDesktop extends JFrame
     VamsasMenu.add(vamsasStop);
     toolsMenu.add(preferences);
     toolsMenu.add(showMemusage);
+    toolsMenu.add(showConsole);
     toolsMenu.add(garbageCollect);
     inputMenu.add(inputLocalFileMenuItem);
     inputMenu.add(inputURLMenuItem);
@@ -331,6 +342,12 @@ public class GDesktop extends JFrame
     // inputMenu.add(vamsasLoad);
   }
 
+  protected void showConsole_actionPerformed(ActionEvent e)
+  {
+    // TODO Auto-generated method stub
+    
+  }
+
   protected void showMemusage_actionPerformed(ActionEvent e)
   {
     // TODO Auto-generated method stub