oburn       2003/02/25 04:49:15

  Modified:    src/java/org/apache/log4j/chainsaw ControlPanel.java
                        ExitAction.java LoadXMLAction.java Main.java
                        XMLFileHandler.java
  Log:
  Patch from Raymond DeCampo:
  
  Chainsaw is now capable of remembering the size and position of the main
  window, the position of the table/details divider, the width and order
  of all the columns, whether or not each column is displayed, the state
  of the filtes and a recent files list.  The number of files in the
  recent files list is configurable, as is the whether the state of the
  filters is preserved.  These preferences are accessible from the
  File->Preferences menu option.  The preference dialog also allows the
  user to select which columns are shown.  Mnemonic shortcuts have been
  added to all menu items.  The recent files submenu is under the File
  menu.  The preferences are stored under the user's home directorey by
  default but the preference file and any individual preference may be
  overridden by the system properties.  Chainsaw will handle the absence
  of the preferences file by creating it; no errors should arise from any
  preference not being defined.
  
  Revision  Changes    Path
  1.5       +151 -56   
jakarta-log4j/src/java/org/apache/log4j/chainsaw/ControlPanel.java
  
  Index: ControlPanel.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-log4j/src/java/org/apache/log4j/chainsaw/ControlPanel.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ControlPanel.java 5 Feb 2003 11:11:11 -0000       1.4
  +++ ControlPanel.java 25 Feb 2003 12:49:14 -0000      1.5
  @@ -1,9 +1,51 @@
   /*
  - * Copyright (C) The Apache Software Foundation. All rights reserved.
  + * ============================================================================
  + *                   The Apache Software License, Version 1.1
  + * ============================================================================
    *
  - * This software is published under the terms of the Apache Software
  - * License version 1.1, a copy of which has been included with this
  - * distribution in the LICENSE.txt file.  */
  + *    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
  + *
  + * Redistribution and use in source and binary forms, with or without modifica-
  + * tion, are permitted provided that the following conditions are met:
  + *
  + * 1. Redistributions of  source code must  retain the above copyright  notice,
  + *    this list of conditions and the following disclaimer.
  + *
  + * 2. Redistributions in binary form must reproduce the above copyright notice,
  + *    this list of conditions and the following disclaimer in the documentation
  + *    and/or other materials provided with the distribution.
  + *
  + * 3. The end-user documentation included with the redistribution, if any, must
  + *    include  the following  acknowledgment:  "This product includes  software
  + *    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
  + *    Alternately, this  acknowledgment may  appear in the software itself,  if
  + *    and wherever such third-party acknowledgments normally appear.
  + *
  + * 4. The names "log4j" and  "Apache Software Foundation"  must not be used to
  + *    endorse  or promote  products derived  from this  software without  prior
  + *    written permission. For written permission, please contact
  + *    [EMAIL PROTECTED]
  + *
  + * 5. Products  derived from this software may not  be called "Apache", nor may
  + *    "Apache" appear  in their name,  without prior written permission  of the
  + *    Apache Software Foundation.
  + *
  + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  + * FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
  + * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
  + * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
  + * DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
  + * OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
  + * ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
  + * (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
  + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  + *
  + * This software  consists of voluntary contributions made  by many individuals
  + * on  behalf of the Apache Software  Foundation.  For more  information on the
  + * Apache Software Foundation, please see <http://www.apache.org/>.
  + *
  + */
   package org.apache.log4j.chainsaw;
   
   import java.awt.GridBagConstraints;
  @@ -30,6 +72,22 @@
    * @author <a href="mailto:[EMAIL PROTECTED]">Oliver Burn</a>
    */
   class ControlPanel extends JPanel {
  +
  +    /** Name of the preference set for the control panel */
  +    public static final String PREF_SET_NAME = "filter";
  +    /** Priority filter property */
  +    public static final String PRIORITY_PROPERTY = "priority";
  +    /** Thread filter property */
  +    public static final String THREAD_PROPERTY = "thread";
  +    /** Category filter property */
  +    public static final String CATEGORY_PROPERTY = "category";
  +    /** NDC filter property */
  +    public static final String NDC_PROPERTY = "ndc";
  +    /** Message filter property */
  +    public static final String MESSAGE_PROPERTY = "message";
  +    /** Save filters? property */
  +    public static final String SAVE_PROPERTY = "save";
  +
       /** use the log messages **/
       private static final Category LOG =
                                     Category.getInstance(ControlPanel.class);
  @@ -40,10 +98,14 @@
        * @param aModel the model to control
        */
       ControlPanel(final MyTableModel aModel) {
  +        final PreferenceSet prefs = Preferences.getInstance().getPreferenceSet(
  +            Preferences.PROP_PREFIX, PREF_SET_NAME);
  +        final boolean savePrefs = prefs.getBoolean(SAVE_PROPERTY, true);
  +
           setBorder(BorderFactory.createTitledBorder("Controls: "));
           final GridBagLayout gridbag = new GridBagLayout();
           final GridBagConstraints c = new GridBagConstraints();
  -     final Dimension d = new Dimension(80,24);
  +        final Dimension d = new Dimension(80,24);
           setLayout(gridbag);
   
           // Pad everything
  @@ -88,9 +150,6 @@
           c.gridy = 0;
           final Priority[] allPriorities = Priority.getAllPossiblePriorities();
           final JComboBox priorities = new JComboBox(allPriorities);
  -        final Priority lowest = allPriorities[allPriorities.length - 1];
  -        priorities.setSelectedItem(lowest);
  -        aModel.setPriorityFilter(lowest);
           gridbag.setConstraints(priorities, c);
           add(priorities);
           priorities.setEditable(false);
  @@ -98,71 +157,89 @@
                   public void actionPerformed(ActionEvent aEvent) {
                       aModel.setPriorityFilter(
                           (Priority) priorities.getSelectedItem());
  +                    prefs.setProperty(PRIORITY_PROPERTY,
  +                        priorities.getSelectedItem().toString());
                   }
               });
   
  +        Priority selected = allPriorities[allPriorities.length - 1];
  +        final String priorityProp = prefs.getProperty(PRIORITY_PROPERTY);
  +        if (savePrefs && priorityProp != null) {
  +            for (int i = 0; i < allPriorities.length; i++) {
  +                if (allPriorities[i].toString().equals(priorityProp)) {
  +                    selected = allPriorities[i];
  +                    break;
  +                }
  +            }
  +        }
  +        priorities.setSelectedItem(selected);
  +        aModel.setPriorityFilter(selected);
   
           c.fill = GridBagConstraints.HORIZONTAL;
  -     c.gridwidth = 2;
  +        c.gridwidth = 2;
           c.gridy++;
  -        final JTextField threadField = new JTextField("");
  -        threadField.getDocument().addDocumentListener(new DocumentListener () {
  -                public void insertUpdate(DocumentEvent aEvent) {
  -                    aModel.setThreadFilter(threadField.getText());
  -                }
  -                public void removeUpdate(DocumentEvent aEvente) {
  -                    aModel.setThreadFilter(threadField.getText());
  -                }
  -                public void changedUpdate(DocumentEvent aEvent) {
  +        String threadProp = "";
  +        if (savePrefs) {
  +            threadProp = prefs.getProperty(THREAD_PROPERTY, "");
  +        }
  +        final JTextField threadField = new JTextField(threadProp);
  +        aModel.setThreadFilter(threadProp);
  +        threadField.getDocument().addDocumentListener(
  +            new DocumentChangeListener () {
  +                public void update(DocumentEvent aEvent) {
                       aModel.setThreadFilter(threadField.getText());
  +                    prefs.setProperty(THREAD_PROPERTY, threadField.getText());
                   }
               });
           gridbag.setConstraints(threadField, c);
           add(threadField);
   
           c.gridy++;
  -        final JTextField catField = new JTextField("");
  -        catField.getDocument().addDocumentListener(new DocumentListener () {
  -                public void insertUpdate(DocumentEvent aEvent) {
  -                    aModel.setCategoryFilter(catField.getText());
  -                }
  -                public void removeUpdate(DocumentEvent aEvent) {
  -                    aModel.setCategoryFilter(catField.getText());
  -                }
  -                public void changedUpdate(DocumentEvent aEvent) {
  +        String catProp = "";
  +        if (savePrefs) {
  +            catProp = prefs.getProperty(CATEGORY_PROPERTY, "");
  +        }
  +        final JTextField catField = new JTextField(catProp);
  +        aModel.setCategoryFilter(catProp);
  +        catField.getDocument().addDocumentListener(
  +            new DocumentChangeListener() {
  +                public void update(DocumentEvent aEvent) {
                       aModel.setCategoryFilter(catField.getText());
  +                    prefs.setProperty(CATEGORY_PROPERTY, catField.getText());
                   }
               });
           gridbag.setConstraints(catField, c);
           add(catField);
   
           c.gridy++;
  -        final JTextField ndcField = new JTextField("");
  -        ndcField.getDocument().addDocumentListener(new DocumentListener () {
  -                public void insertUpdate(DocumentEvent aEvent) {
  -                    aModel.setNDCFilter(ndcField.getText());
  -                }
  -                public void removeUpdate(DocumentEvent aEvent) {
  -                    aModel.setNDCFilter(ndcField.getText());
  -                }
  -                public void changedUpdate(DocumentEvent aEvent) {
  +        String ndcProp = "";
  +        if (savePrefs) {
  +            ndcProp = prefs.getProperty(NDC_PROPERTY, "");
  +        }
  +        final JTextField ndcField = new JTextField(ndcProp);
  +        aModel.setNDCFilter(ndcProp);
  +        ndcField.getDocument().addDocumentListener(
  +            new DocumentChangeListener () {
  +                public void update(DocumentEvent aEvent) {
                       aModel.setNDCFilter(ndcField.getText());
  +                    prefs.setProperty(NDC_PROPERTY, ndcField.getText());
                   }
               });
           gridbag.setConstraints(ndcField, c);
           add(ndcField);
   
           c.gridy++;
  -        final JTextField msgField = new JTextField("");
  -        msgField.getDocument().addDocumentListener(new DocumentListener () {
  -                public void insertUpdate(DocumentEvent aEvent) {
  -                    aModel.setMessageFilter(msgField.getText());
  -                }
  -                public void removeUpdate(DocumentEvent aEvent) {
  -                    aModel.setMessageFilter(msgField.getText());
  -                }
  -                public void changedUpdate(DocumentEvent aEvent) {
  +        String msgProp = "";
  +        if (savePrefs) {
  +            msgProp = prefs.getProperty(MESSAGE_PROPERTY, "");
  +        }
  +        final JTextField msgField = new JTextField(msgProp);
  +        aModel.setMessageFilter(msgProp);
  +        msgField.getDocument().addDocumentListener(
  +            new DocumentChangeListener () {
  +                public void update(DocumentEvent aEvent) {
                       aModel.setMessageFilter(msgField.getText());
  +                    prefs.setProperty(MESSAGE_PROPERTY, msgField.getText());
                   }
               });
   
  @@ -178,12 +255,12 @@
           c.weighty = 0;
           c.fill = GridBagConstraints.NONE;
           c.anchor = GridBagConstraints.EAST;
  -     final JPanel buttonPanel = new JPanel();
  +    final JPanel buttonPanel = new JPanel();
           gridbag.setConstraints(buttonPanel, c);
           add(buttonPanel);
           buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT,1,1));
   
  -     final Insets insets = new Insets(2,2,2,2);
  +    final Insets insets = new Insets(2,2,2,2);
           final JButton toggleButton = new JButton("Pause");
           toggleButton.setMnemonic('p');
           toggleButton.addActionListener(new ActionListener() {
  @@ -193,9 +270,9 @@
                           aModel.isPaused() ? "Resume" : "Pause");
                   }
               });
  -     toggleButton.setMargin(insets);
  -     toggleButton.setPreferredSize(d);
  -     toggleButton.setMinimumSize(d);
  +    toggleButton.setMargin(insets);
  +    toggleButton.setPreferredSize(d);
  +    toggleButton.setMinimumSize(d);
           buttonPanel.add(toggleButton);
   
           final JButton clearButton = new JButton("Clear");
  @@ -205,18 +282,36 @@
                       aModel.clear();
                   }
               });
  -     clearButton.setMargin(insets);
  -     clearButton.setPreferredSize(d);
  -     clearButton.setMinimumSize(d);
  +    clearButton.setMargin(insets);
  +    clearButton.setPreferredSize(d);
  +    clearButton.setMinimumSize(d);
           buttonPanel.add(clearButton);
   
           final JButton exitButton = new JButton("Exit");
           exitButton.setMnemonic('x');
           exitButton.addActionListener(ExitAction.INSTANCE);
  -     exitButton.setMargin(insets);
  -     exitButton.setPreferredSize(d);
  -     exitButton.setMinimumSize(d);
  +    exitButton.setMargin(insets);
  +    exitButton.setPreferredSize(d);
  +    exitButton.setMinimumSize(d);
           buttonPanel.add(exitButton);
  +    }
  +
  +    /** Convenience class that filters all document events to one method */
  +    private static abstract class DocumentChangeListener
  +        implements DocumentListener {
  +
  +        public abstract void update(DocumentEvent aEvent);
  +
  +        public void insertUpdate(DocumentEvent aEvent) {
  +            update(aEvent);
  +        }
  +        public void removeUpdate(DocumentEvent aEvent) {
  +            update(aEvent);
  +        }
  +        public void changedUpdate(DocumentEvent aEvent) {
  +            update(aEvent);
  +        }
   
       }
  +
   }
  
  
  
  1.2       +84 -4     jakarta-log4j/src/java/org/apache/log4j/chainsaw/ExitAction.java
  
  Index: ExitAction.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-log4j/src/java/org/apache/log4j/chainsaw/ExitAction.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ExitAction.java   23 Mar 2002 07:51:26 -0000      1.1
  +++ ExitAction.java   25 Feb 2003 12:49:14 -0000      1.2
  @@ -1,12 +1,58 @@
   /*
  - * Copyright (C) The Apache Software Foundation. All rights reserved.
  + * ============================================================================
  + *                   The Apache Software License, Version 1.1
  + * ============================================================================
    *
  - * This software is published under the terms of the Apache Software
  - * License version 1.1, a copy of which has been included with this
  - * distribution in the LICENSE.txt file.  */
  + *    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
  + *
  + * Redistribution and use in source and binary forms, with or without modifica-
  + * tion, are permitted provided that the following conditions are met:
  + *
  + * 1. Redistributions of  source code must  retain the above copyright  notice,
  + *    this list of conditions and the following disclaimer.
  + *
  + * 2. Redistributions in binary form must reproduce the above copyright notice,
  + *    this list of conditions and the following disclaimer in the documentation
  + *    and/or other materials provided with the distribution.
  + *
  + * 3. The end-user documentation included with the redistribution, if any, must
  + *    include  the following  acknowledgment:  "This product includes  software
  + *    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
  + *    Alternately, this  acknowledgment may  appear in the software itself,  if
  + *    and wherever such third-party acknowledgments normally appear.
  + *
  + * 4. The names "log4j" and  "Apache Software Foundation"  must not be used to
  + *    endorse  or promote  products derived  from this  software without  prior
  + *    written permission. For written permission, please contact
  + *    [EMAIL PROTECTED]
  + *
  + * 5. Products  derived from this software may not  be called "Apache", nor may
  + *    "Apache" appear  in their name,  without prior written permission  of the
  + *    Apache Software Foundation.
  + *
  + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  + * FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
  + * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
  + * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
  + * DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
  + * OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
  + * ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
  + * (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
  + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  + *
  + * This software  consists of voluntary contributions made  by many individuals
  + * on  behalf of the Apache Software  Foundation.  For more  information on the
  + * Apache Software Foundation, please see <http://www.apache.org/>.
  + *
  + */
   package org.apache.log4j.chainsaw;
   
   import java.awt.event.ActionEvent;
  +import java.util.Collections;
  +import java.util.Iterator;
  +import java.util.List;
  +import java.util.LinkedList;
   import javax.swing.AbstractAction;
   import org.apache.log4j.Category;
   
  @@ -24,6 +70,12 @@
       /** The instance to share **/
       public static final ExitAction INSTANCE = new ExitAction();
   
  +    /** hooks to call on shutdown */
  +    private final List mShutdownHooks =
  +        Collections.synchronizedList(new LinkedList());
  +    /** flag to indicate if shutting down */
  +    private boolean mShuttingDown = false;
  +
       /** Stop people creating instances **/
       private ExitAction() {}
   
  @@ -33,6 +85,34 @@
        */
       public void actionPerformed(ActionEvent aIgnore) {
           LOG.info("shutting down");
  +        mShuttingDown = true;
  +        for (Iterator i = mShutdownHooks.iterator(); i.hasNext(); ) {
  +            try {
  +                final Thread t = (Thread) i.next();
  +                t.start();
  +                t.join(500);
  +            } catch (final Throwable t) {
  +                // Don't let anything stop us
  +                LOG.error(t.getMessage(), t);
  +            }
  +            try {
  +                Preferences.getInstance().save();
  +            } catch (final Throwable t) {
  +                LOG.error("Could not save preferences: " + t.getMessage(), t);
  +            }
  +        }
           System.exit(0);
  +    }
  +
  +    /**
  +     *  Register a Thread to fire before the system is shut down.  Use this
  +     *  methos instead of Runtime.addShutdownHook() for JDK 1.2.x compatibility.
  +     *
  +     *  @param aShutdownHook  thread to run upon exit
  +     */
  +    public void addShutdownHook(Thread aShutdownHook) {
  +        if (!mShuttingDown) {
  +            mShutdownHooks.add(aShutdownHook);
  +        }
       }
   }
  
  
  
  1.2       +49 -49    
jakarta-log4j/src/java/org/apache/log4j/chainsaw/LoadXMLAction.java
  
  Index: LoadXMLAction.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-log4j/src/java/org/apache/log4j/chainsaw/LoadXMLAction.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- LoadXMLAction.java        23 Mar 2002 07:51:26 -0000      1.1
  +++ LoadXMLAction.java        25 Feb 2003 12:49:14 -0000      1.2
  @@ -1,25 +1,62 @@
   /*
  - * Copyright (C) The Apache Software Foundation. All rights reserved.
  + * ============================================================================
  + *                   The Apache Software License, Version 1.1
  + * ============================================================================
    *
  - * This software is published under the terms of the Apache Software
  - * License version 1.1, a copy of which has been included with this
  - * distribution in the LICENSE.txt file.  */
  + *    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
  + *
  + * Redistribution and use in source and binary forms, with or without modifica-
  + * tion, are permitted provided that the following conditions are met:
  + *
  + * 1. Redistributions of  source code must  retain the above copyright  notice,
  + *    this list of conditions and the following disclaimer.
  + *
  + * 2. Redistributions in binary form must reproduce the above copyright notice,
  + *    this list of conditions and the following disclaimer in the documentation
  + *    and/or other materials provided with the distribution.
  + *
  + * 3. The end-user documentation included with the redistribution, if any, must
  + *    include  the following  acknowledgment:  "This product includes  software
  + *    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
  + *    Alternately, this  acknowledgment may  appear in the software itself,  if
  + *    and wherever such third-party acknowledgments normally appear.
  + *
  + * 4. The names "log4j" and  "Apache Software Foundation"  must not be used to
  + *    endorse  or promote  products derived  from this  software without  prior
  + *    written permission. For written permission, please contact
  + *    [EMAIL PROTECTED]
  + *
  + * 5. Products  derived from this software may not  be called "Apache", nor may
  + *    "Apache" appear  in their name,  without prior written permission  of the
  + *    Apache Software Foundation.
  + *
  + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  + * FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
  + * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
  + * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
  + * DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
  + * OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
  + * ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
  + * (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
  + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  + *
  + * This software  consists of voluntary contributions made  by many individuals
  + * on  behalf of the Apache Software  Foundation.  For more  information on the
  + * Apache Software Foundation, please see <http://www.apache.org/>.
  + *
  + */
   package org.apache.log4j.chainsaw;
   
   import java.awt.event.ActionEvent;
   import java.io.File;
  -import java.io.IOException;
  -import java.io.StringReader;
  +
   import javax.swing.AbstractAction;
   import javax.swing.JFileChooser;
   import javax.swing.JFrame;
   import javax.swing.JOptionPane;
  -import javax.xml.parsers.ParserConfigurationException;
  -import javax.xml.parsers.SAXParserFactory;
  +
   import org.apache.log4j.Category;
  -import org.xml.sax.InputSource;
  -import org.xml.sax.SAXException;
  -import org.xml.sax.XMLReader;
   
   /**
    * Encapsulates the action to load an XML file.
  @@ -47,8 +84,6 @@
           mChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
       }
   
  -    /** parser to read XML files **/
  -    private final XMLReader mParser;
       /** the content handler **/
       private final XMLFileHandler mHandler;
   
  @@ -58,16 +93,11 @@
        *
        * @param aParent the parent frame
        * @param aModel the model to add events to
  -     * @exception SAXException if an error occurs
  -     * @throws ParserConfigurationException if an error occurs
        */
       LoadXMLAction(JFrame aParent, MyTableModel aModel)
  -        throws SAXException, ParserConfigurationException
       {
           mParent = aParent;
           mHandler = new XMLFileHandler(aModel);
  -        mParser = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
  -        mParser.setContentHandler(mHandler);
       }
   
       /**
  @@ -79,9 +109,8 @@
           if (mChooser.showOpenDialog(mParent) == JFileChooser.APPROVE_OPTION) {
               LOG.info("Need to load a file");
               final File chosen = mChooser.getSelectedFile();
  -            LOG.info("loading the contents of " + chosen.getAbsolutePath());
               try {
  -                final int num = loadFile(chosen.getAbsolutePath());
  +                final int num = mHandler.loadFile(chosen);
                   JOptionPane.showMessageDialog(
                       mParent,
                       "Loaded " + num + " events.",
  @@ -98,33 +127,4 @@
           }
       }
   
  -    /**
  -     * Loads the contents of file into the model
  -     *
  -     * @param aFile the file to extract events from
  -     * @return the number of events loaded
  -     * @throws SAXException if an error occurs
  -     * @throws IOException if an error occurs
  -     */
  -    private int loadFile(String aFile)
  -        throws SAXException, IOException
  -    {
  -        synchronized (mParser) {
  -            // Create a dummy document to parse the file
  -            final StringBuffer buf = new StringBuffer();
  -            buf.append("<?xml version=\"1.0\" standalone=\"yes\"?>\n");
  -            buf.append("<!DOCTYPE log4j:eventSet ");
  -            buf.append("[<!ENTITY data SYSTEM \"file:///");
  -            buf.append(aFile);
  -            buf.append("\">]>\n");
  -            buf.append("<log4j:eventSet xmlns:log4j=\"Claira\">\n");
  -            buf.append("&data;\n");
  -            buf.append("</log4j:eventSet>\n");
  -
  -            final InputSource is =
  -                new InputSource(new StringReader(buf.toString()));
  -            mParser.parse(is);
  -            return mHandler.getNumEvents();
  -        }
  -    }
   }
  
  
  
  1.4       +135 -9    jakarta-log4j/src/java/org/apache/log4j/chainsaw/Main.java
  
  Index: Main.java
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/src/java/org/apache/log4j/chainsaw/Main.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Main.java 24 Feb 2003 05:38:08 -0000      1.3
  +++ Main.java 25 Feb 2003 12:49:14 -0000      1.4
  @@ -1,13 +1,57 @@
   /*
  - * Copyright (C) The Apache Software Foundation. All rights reserved.
  + * ============================================================================
  + *                   The Apache Software License, Version 1.1
  + * ============================================================================
    *
  - * This software is published under the terms of the Apache Software
  - * License version 1.1, a copy of which has been included with this
  - * distribution in the LICENSE.txt file.  */
  + *    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
  + *
  + * Redistribution and use in source and binary forms, with or without modifica-
  + * tion, are permitted provided that the following conditions are met:
  + *
  + * 1. Redistributions of  source code must  retain the above copyright  notice,
  + *    this list of conditions and the following disclaimer.
  + *
  + * 2. Redistributions in binary form must reproduce the above copyright notice,
  + *    this list of conditions and the following disclaimer in the documentation
  + *    and/or other materials provided with the distribution.
  + *
  + * 3. The end-user documentation included with the redistribution, if any, must
  + *    include  the following  acknowledgment:  "This product includes  software
  + *    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
  + *    Alternately, this  acknowledgment may  appear in the software itself,  if
  + *    and wherever such third-party acknowledgments normally appear.
  + *
  + * 4. The names "log4j" and  "Apache Software Foundation"  must not be used to
  + *    endorse  or promote  products derived  from this  software without  prior
  + *    written permission. For written permission, please contact
  + *    [EMAIL PROTECTED]
  + *
  + * 5. Products  derived from this software may not  be called "Apache", nor may
  + *    "Apache" appear  in their name,  without prior written permission  of the
  + *    Apache Software Foundation.
  + *
  + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  + * FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
  + * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
  + * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
  + * DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
  + * OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
  + * ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
  + * (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
  + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  + *
  + * This software  consists of voluntary contributions made  by many individuals
  + * on  behalf of the Apache Software  Foundation.  For more  information on the
  + * Apache Software Foundation, please see <http://www.apache.org/>.
  + *
  + */
   package org.apache.log4j.chainsaw;
   
   import java.awt.BorderLayout;
   import java.awt.Dimension;
  +import java.awt.event.ActionListener;
  +import java.awt.event.ActionEvent;
   import java.awt.event.WindowAdapter;
   import java.awt.event.WindowEvent;
   import java.io.IOException;
  @@ -40,27 +84,53 @@
       /** name of property for port name **/
       public static final String PORT_PROP_NAME = "chainsaw.port";
   
  +    /** Window x-position property */
  +    public static final String X_POSITION_PROPERTY =
  +        Preferences.PROP_PREFIX + ".x";
  +    /** Window y-position property */
  +    public static final String Y_POSITION_PROPERTY =
  +        Preferences.PROP_PREFIX + ".y";
  +    /** Window width property */
  +    public static final String WIDTH_PROPERTY =
  +        Preferences.PROP_PREFIX + ".width";
  +    /** Window height property */
  +    public static final String HEIGHT_PROPERTY =
  +        Preferences.PROP_PREFIX + ".height";
  +    /** Details/table separator position property */
  +    public static final String DETAILS_SEPARATOR_PROPERTY =
  +        Preferences.PROP_PREFIX + ".details.separator";
  +
       /** use to log messages **/
       private static final Category LOG = Category.getInstance(Main.class);
   
  +    private static final Preferences PREFS = Preferences.getInstance();
  +
  +    private final JSplitPane aDetailsDivider;
  +    private final MyTableColumnModel mColumnModel;
   
       /**
        * Creates a new <code>Main</code> instance.
        */
       private Main() {
           super("CHAINSAW - Log4J Log Viewer");
  +
  +        ExitAction.INSTANCE.addShutdownHook(new Thread(new Shutdown()));
  +
           // create the all important model
           final MyTableModel model = new MyTableModel();
  +        mColumnModel = new MyTableColumnModel(model);
   
           //Create the menu bar.
           final JMenuBar menuBar = new JMenuBar();
           setJMenuBar(menuBar);
           final JMenu menu = new JMenu("File");
  +        menu.setMnemonic('F');
           menuBar.add(menu);
   
           try {
               final LoadXMLAction lxa = new LoadXMLAction(this, model);
               final JMenuItem loadMenuItem = new JMenuItem("Load file...");
  +            loadMenuItem.setMnemonic('L');
               menu.add(loadMenuItem);
               loadMenuItem.addActionListener(lxa);
           } catch (NoClassDefFoundError e) {
  @@ -79,7 +149,23 @@
                   JOptionPane.ERROR_MESSAGE);
           }
   
  +        final RecentFilesMenu recent = new RecentFilesMenu(model);
  +        recent.setMnemonic('R');
  +        menu.add(recent);
  +        PREFS.setRecentFilesMenu(recent);
  +        recent.rebuild();
  +
  +        final JMenuItem prefsMenuItem = new JMenuItem("Preferences");
  +        prefsMenuItem.setMnemonic('P');
  +        menu.add(prefsMenuItem);
  +        prefsMenuItem.addActionListener(new ActionListener() {
  +            public void actionPerformed(ActionEvent ae) {
  +                new PreferencesDialog(Main.this, mColumnModel).show();
  +            }
  +        });
  +
           final JMenuItem exitMenuItem = new JMenuItem("Exit");
  +        exitMenuItem.setMnemonic('x');
           menu.add(exitMenuItem);
           exitMenuItem.addActionListener(ExitAction.INSTANCE);
   
  @@ -88,7 +174,8 @@
           getContentPane().add(cp, BorderLayout.NORTH);
   
           // Create the table
  -        final JTable table = new JTable(model);
  +        final JTable table = new JTable(model, mColumnModel);
  +        table.setAutoCreateColumnsFromModel(true);
           table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
           final JScrollPane scrollPane = new JScrollPane(table);
           scrollPane.setBorder(BorderFactory.createTitledBorder("Events: "));
  @@ -99,9 +186,9 @@
           details.setPreferredSize(new Dimension(900, 100));
   
           // Add the table and stack trace into a splitter
  -        final JSplitPane jsp =
  -            new JSplitPane(JSplitPane.VERTICAL_SPLIT, scrollPane, details);
  -        getContentPane().add(jsp, BorderLayout.CENTER);
  +        aDetailsDivider = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
  +            scrollPane, details);
  +        getContentPane().add(aDetailsDivider, BorderLayout.CENTER);
   
           addWindowListener(new WindowAdapter() {
                   public void windowClosing(WindowEvent aEvent) {
  @@ -109,7 +196,7 @@
                   }
               });
   
  -        pack();
  +        loadGuiPrefs();
           setVisible(true);
   
           setupReceiver(model);
  @@ -153,6 +240,39 @@
           }
       }
   
  +    private void loadGuiPrefs() {
  +        // table prefs
  +        mColumnModel.loadPrefs();
  +
  +        final int divider = PREFS.getInteger(DETAILS_SEPARATOR_PROPERTY, -1);
  +        if (divider > 0) {
  +            aDetailsDivider.setDividerLocation(divider);
  +        }
  +
  +        final int x = PREFS.getInteger(X_POSITION_PROPERTY, 0);
  +        final int y = PREFS.getInteger(Y_POSITION_PROPERTY, 0);
  +        setLocation(x, y);
  +
  +        final int width = PREFS.getInteger(WIDTH_PROPERTY, 0);
  +        final int height = PREFS.getInteger(HEIGHT_PROPERTY, 0);
  +        if ((width > 0) && (height > 0)) {
  +            setSize(width, height);
  +        } else {
  +            pack();
  +        }
  +    }
  +
  +    private void saveGuiPrefs() {
  +        mColumnModel.savePrefs();
  +
  +        PREFS.setInteger(DETAILS_SEPARATOR_PROPERTY,
  +            aDetailsDivider.getDividerLocation());
  +        PREFS.setInteger(X_POSITION_PROPERTY, getX());
  +        PREFS.setInteger(Y_POSITION_PROPERTY, getY());
  +        PREFS.setInteger(WIDTH_PROPERTY, getWidth());
  +        PREFS.setInteger(HEIGHT_PROPERTY, getHeight());
  +    }
  +
   
       ////////////////////////////////////////////////////////////////////////////
       // static methods
  @@ -178,5 +298,11 @@
       public static void main(String[] aArgs) {
           initLog4J();
           new Main();
  +    }
  +
  +    private class Shutdown implements Runnable {
  +        public void run() {
  +            saveGuiPrefs();
  +        }
       }
   }
  
  
  
  1.6       +99 -4     
jakarta-log4j/src/java/org/apache/log4j/chainsaw/XMLFileHandler.java
  
  Index: XMLFileHandler.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-log4j/src/java/org/apache/log4j/chainsaw/XMLFileHandler.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- XMLFileHandler.java       10 Feb 2003 10:52:30 -0000      1.5
  +++ XMLFileHandler.java       25 Feb 2003 12:49:14 -0000      1.6
  @@ -1,15 +1,65 @@
   /*
  - * Copyright (C) The Apache Software Foundation. All rights reserved.
  + * ============================================================================
  + *                   The Apache Software License, Version 1.1
  + * ============================================================================
    *
  - * This software is published under the terms of the Apache Software
  - * License version 1.1, a copy of which has been included with this
  - * distribution in the LICENSE.txt file.  */
  + *    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
  + *
  + * Redistribution and use in source and binary forms, with or without modifica-
  + * tion, are permitted provided that the following conditions are met:
  + *
  + * 1. Redistributions of  source code must  retain the above copyright  notice,
  + *    this list of conditions and the following disclaimer.
  + *
  + * 2. Redistributions in binary form must reproduce the above copyright notice,
  + *    this list of conditions and the following disclaimer in the documentation
  + *    and/or other materials provided with the distribution.
  + *
  + * 3. The end-user documentation included with the redistribution, if any, must
  + *    include  the following  acknowledgment:  "This product includes  software
  + *    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
  + *    Alternately, this  acknowledgment may  appear in the software itself,  if
  + *    and wherever such third-party acknowledgments normally appear.
  + *
  + * 4. The names "log4j" and  "Apache Software Foundation"  must not be used to
  + *    endorse  or promote  products derived  from this  software without  prior
  + *    written permission. For written permission, please contact
  + *    [EMAIL PROTECTED]
  + *
  + * 5. Products  derived from this software may not  be called "Apache", nor may
  + *    "Apache" appear  in their name,  without prior written permission  of the
  + *    Apache Software Foundation.
  + *
  + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  + * FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
  + * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
  + * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
  + * DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
  + * OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
  + * ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
  + * (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
  + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  + *
  + * This software  consists of voluntary contributions made  by many individuals
  + * on  behalf of the Apache Software  Foundation.  For more  information on the
  + * Apache Software Foundation, please see <http://www.apache.org/>.
  + *
  + */
   package org.apache.log4j.chainsaw;
   
  +import java.io.File;
  +import java.io.IOException;
  +import java.io.StringReader;
   import java.util.StringTokenizer;
  +import javax.xml.parsers.SAXParserFactory;
  +import javax.xml.parsers.ParserConfigurationException;
  +import org.apache.log4j.Logger;
   import org.apache.log4j.Priority;
   import org.xml.sax.Attributes;
  +import org.xml.sax.InputSource;
   import org.xml.sax.SAXException;
  +import org.xml.sax.XMLReader;
   import org.xml.sax.helpers.DefaultHandler;
   
   /**
  @@ -22,6 +72,8 @@
   class XMLFileHandler
       extends DefaultHandler
   {
  +    private static final Logger LOG = Logger.getLogger(XMLFileHandler.class);
  +
       /** represents the event tag **/
       private static final String TAG_EVENT = "log4j:event";
       /** represents the message tag **/
  @@ -132,6 +184,16 @@
           return mNumEvents;
       }
   
  +    public int loadFile(File file)
  +        throws SAXException, IOException, ParserConfigurationException {
  +
  +        final String absPath = file.getAbsolutePath();
  +        LOG.info("loading the contents of " + absPath);
  +        final int num = loadFile(absPath);
  +        Preferences.getInstance().fileLoaded(absPath);
  +        return num;
  +    }
  +
       ////////////////////////////////////////////////////////////////////////////
       // Private methods
       ////////////////////////////////////////////////////////////////////////////
  @@ -159,5 +221,38 @@
           mMessage = null;
           mThrowableStrRep = null;
           mLocationDetails = null;
  +    }
  +
  +    /**
  +     * Loads the contents of file into the model
  +     *
  +     * @param aFile the file to extract events from
  +     * @return the number of events loaded
  +     * @throws SAXException if an error occurs
  +     * @throws IOException if an error occurs
  +     */
  +    private int loadFile(String aFile)
  +        throws SAXException, IOException, ParserConfigurationException {
  +        final XMLReader parser =
  +            SAXParserFactory.newInstance().newSAXParser().getXMLReader();
  +        parser.setContentHandler(this);
  +
  +        synchronized (parser) {
  +            // Create a dummy document to parse the file
  +            final StringBuffer buf = new StringBuffer();
  +            buf.append("<?xml version=\"1.0\" standalone=\"yes\"?>\n");
  +            buf.append("<!DOCTYPE log4j:eventSet ");
  +            buf.append("[<!ENTITY data SYSTEM \"file:///");
  +            buf.append(aFile);
  +            buf.append("\">]>\n");
  +            buf.append("<log4j:eventSet xmlns:log4j=\"Claira\">\n");
  +            buf.append("&data;\n");
  +            buf.append("</log4j:eventSet>\n");
  +
  +            final InputSource is =
  +                new InputSource(new StringReader(buf.toString()));
  +            parser.parse(is);
  +            return getNumEvents();
  +        }
       }
   }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to