You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by ps...@apache.org on 2004/09/02 02:30:19 UTC

cvs commit: logging-log4j/src/java/org/apache/log4j/chainsaw/dnd FileDnDTarget.java

psmith      2004/09/01 17:30:19

  Modified:    src/java/org/apache/log4j/chainsaw/version
                        VersionManager.java
               src/java/org/apache/log4j/chainsaw ChainsawTabbedPane.java
                        LogUI.java FileLoadAction.java
                        ChainsawToolBarAndMenus.java
               src/java/org/apache/log4j/chainsaw/help release-notes.html
  Added:       src/java/org/apache/log4j/chainsaw/dnd FileDnDTarget.java
  Log:
  * Added Drag & Drop (rudimentary) support to Chainsaw.   You can drag any File to Chainsaw's
    Tabbed Pane area and it will try to load it.  If there are no events in the file, not a lot happens...
  
  * Fixed a condition where loading an XML configuration file did not properly use the
    correct classloader
  
  * Changed the way the Tabbed Pane functionality works, new tabs are added at the end and
    the new tab is not made active.
  
  Revision  Changes    Path
  1.14      +1 -1      logging-log4j/src/java/org/apache/log4j/chainsaw/version/VersionManager.java
  
  Index: VersionManager.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/chainsaw/version/VersionManager.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- VersionManager.java	19 Aug 2004 22:36:44 -0000	1.13
  +++ VersionManager.java	2 Sep 2004 00:30:18 -0000	1.14
  @@ -10,7 +10,7 @@
   
       private static final VersionManager instance = new VersionManager();
       
  -    private static final String VERSION_INFO = "1.99.99 (20 Aug 2004)";
  +    private static final String VERSION_INFO = "1.99.99 (2 Sep 2004)";
       
       public static final VersionManager getInstance() {
           return instance;
  
  
  
  1.7       +4 -15     logging-log4j/src/java/org/apache/log4j/chainsaw/ChainsawTabbedPane.java
  
  Index: ChainsawTabbedPane.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/chainsaw/ChainsawTabbedPane.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- ChainsawTabbedPane.java	4 Jun 2004 06:00:20 -0000	1.6
  +++ ChainsawTabbedPane.java	2 Sep 2004 00:30:19 -0000	1.7
  @@ -75,14 +75,9 @@
      * @param name
      * @param component
      */
  -  public void addANewTab(String name, JComponent component, Icon icon) {
  +  public synchronized void addANewTab(String name, JComponent component, Icon icon) {
       int selectedIndex = getSelectedIndex();
  -    super.insertTab(name, icon, component, null, 0);
  -
  -    //only select the previously existing tab if there is more than one tab
  -    if (getTabCount() > 1) {
  -      setSelectedIndex(Math.min(selectedIndex + 1, getTabCount() - 1));
  -    }
  +    super.insertTab(name, icon, component, null, getTabCount());
   
       super.fireStateChanged();
     }
  @@ -97,15 +92,9 @@
       super.fireStateChanged();
     }
   
  -  public void addANewTab(
  +  public synchronized void addANewTab(
       String name, JComponent component, Icon icon, String tooltip) {
  -    int selectedIndex = getSelectedIndex();
  -    super.insertTab(name, icon, component, tooltip, 0);
  -
  -    if (getTabCount() >= (selectedIndex + 1)) {
  -      setSelectedIndex(selectedIndex + 1);
  -    }
  -
  +    super.insertTab(name, icon, component, tooltip, getTabCount());
       super.fireStateChanged();
     }
   
  
  
  
  1.104     +108 -71   logging-log4j/src/java/org/apache/log4j/chainsaw/LogUI.java
  
  Index: LogUI.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/chainsaw/LogUI.java,v
  retrieving revision 1.103
  retrieving revision 1.104
  diff -u -r1.103 -r1.104
  --- LogUI.java	28 Jul 2004 08:02:17 -0000	1.103
  +++ LogUI.java	2 Sep 2004 00:30:19 -0000	1.104
  @@ -36,6 +36,7 @@
   import java.awt.event.WindowEvent;
   import java.beans.PropertyChangeEvent;
   import java.beans.PropertyChangeListener;
  +import java.io.File;
   import java.io.IOException;
   import java.lang.reflect.Method;
   import java.net.MalformedURLException;
  @@ -63,6 +64,7 @@
   import javax.swing.JDialog;
   import javax.swing.JEditorPane;
   import javax.swing.JFrame;
  +import javax.swing.JLabel;
   import javax.swing.JOptionPane;
   import javax.swing.JPanel;
   import javax.swing.JPopupMenu;
  @@ -85,6 +87,7 @@
   import org.apache.log4j.AppenderSkeleton;
   import org.apache.log4j.Level;
   import org.apache.log4j.LogManager;
  +import org.apache.log4j.chainsaw.dnd.FileDnDTarget;
   import org.apache.log4j.chainsaw.help.HelpManager;
   import org.apache.log4j.chainsaw.help.Tutorial;
   import org.apache.log4j.chainsaw.helper.SwingHelper;
  @@ -100,7 +103,6 @@
   import org.apache.log4j.chainsaw.receivers.ReceiversPanel;
   import org.apache.log4j.chainsaw.version.VersionManager;
   import org.apache.log4j.helpers.LogLog;
  -import org.apache.log4j.helpers.OptionConverter;
   import org.apache.log4j.joran.JoranConfigurator;
   import org.apache.log4j.net.SocketNodeEventListener;
   import org.apache.log4j.plugins.Plugin;
  @@ -110,7 +112,9 @@
   import org.apache.log4j.plugins.Receiver;
   import org.apache.log4j.rule.ExpressionRule;
   import org.apache.log4j.rule.Rule;
  +import org.apache.log4j.spi.Decoder;
   import org.apache.log4j.spi.LoggingEvent;
  +import org.apache.log4j.xml.XMLDecoder;
   
   
   /**
  @@ -124,7 +128,6 @@
    *
    */
   public class LogUI extends JFrame implements ChainsawViewer, SettingsListener {
  -  private static final String CONFIG_FILE_TO_USE = "config.file";
     private static final String MAIN_WINDOW_HEIGHT = "main.window.height";
     private static final String MAIN_WINDOW_WIDTH = "main.window.width";
     private static final String MAIN_WINDOW_Y = "main.window.y";
  @@ -132,7 +135,6 @@
     private static ChainsawSplash splash;
     private static final double DEFAULT_MAIN_RECEIVER_SPLIT_LOCATION = .8d;
     private final JFrame preferencesFrame = new JFrame();
  -  private URL configURLToUse;
     private boolean noReceiversDefined;
     private ReceiversPanel receiversPanel;
     private ChainsawTabbedPane tabbedPane;
  @@ -304,24 +306,18 @@
       String config = model.getConfigurationURL();
       if(config!=null && (!(config.trim().equals("")))) {
           config = config.trim();
  -        LogLog.info("Using '" + config + "' for auto-configuration");
           try {
  -          // we temporarily swap the TCCL so that plugins can find resources
  -          Thread.currentThread().setContextClassLoader(classLoader);
  -          JoranConfigurator jc = new JoranConfigurator();
  -          jc.doConfigure(new URL(config), LogManager.getLoggerRepository());
  -          jc.logErrors();
  -        } catch (MalformedURLException e) {
  -          LogLog.error("Failed to use the auto-configuration file", e);
  -        }finally{
  -            // now switch it back...
  -            Thread.currentThread().setContextClassLoader(previousTCCL);
  +          LogLog.info("Using '" + config + "' for auto-configuration");
  +          URL configURL = new URL(config);
  +          logUI.loadConfigurationUsingPluginClassLoader(configURL);
  +        }catch(MalformedURLException e) {
  +            LogLog.error("Failed to convert config string to url", e);
           }
       }else {
           LogLog.info("No auto-configuration file found within the ApplicationPreferenceModel");
  +        logUI.ensureChainsawAppenderHandlerAdded();
       }
       
  -    LogManager.getRootLogger().addAppender(logUI.handler);
       logUI.activateViewer();
   
       logUI.getApplicationPreferenceModel().apply(model);
  @@ -379,8 +375,50 @@
       setToolBarAndMenus(new ChainsawToolBarAndMenus(this));
       toolbar = getToolBarAndMenus().getToolbar();
       setJMenuBar(getToolBarAndMenus().getMenubar());
  +    
       setTabbedPane(new ChainsawTabbedPane());
  +    
  +    /**
  +     * This adds Drag & Drop capability to Chainsaw
  +     */
  +    FileDnDTarget dnDTarget = new FileDnDTarget(tabbedPane);
  +    dnDTarget.addPropertyChangeListener("fileList", new PropertyChangeListener() {
  +
  +        public void propertyChange(PropertyChangeEvent evt) {
  +            final List fileList = (List) evt.getNewValue();
  +            
  +            Thread thread = new Thread(new Runnable() {
   
  +                public void run() {
  +                    LogLog.debug("Loading files: " + fileList);
  +                    for (Iterator iter = fileList.iterator(); iter.hasNext();) {
  +                        File  file = (File) iter.next();
  +                        final Decoder decoder = new XMLDecoder();
  +                        try {
  +                            getStatusBar().setMessage("Loading " + file.getAbsolutePath() + "...");
  +                            FileLoadAction.importURL(handler, decoder, file
  +                                    .getName(), file.toURL());
  +                        } catch (Exception e) {
  +                            String errorMsg = "Failed to import a file";
  +                            LogLog.error(errorMsg, e);
  +                            getStatusBar().setMessage(errorMsg);
  +                        }
  +                    }
  +                    
  +                }});
  +            
  +            thread.setPriority(Thread.MIN_PRIORITY);
  +            thread.start();
  +            
  +        }});
  +   
  +    JLabel lbl  = new JLabel();
  +    lbl.setEnabled(false);
  +    String dndTitle = "Drag & Drop XML log files here";
  +    getTabbedPane().addANewTab(dndTitle,lbl,null, "You can Drag & Drop XML log files onto the Tabbed Pane and they will be loaded into Chainsaw" );
  +    getTabbedPane().setEnabledAt(getTabbedPane().indexOfTab(dndTitle), false);
  +    ensureWelcomePanelVisible();
  +    
       applicationPreferenceModelPanel.setOkCancelActionListener(
         new ActionListener() {
           public void actionPerformed(ActionEvent e) {
  @@ -405,9 +443,9 @@
         });
   
       // TODO this should all be in a config file
  -    ChainsawCentral cc = new ChainsawCentral();
  -    pluginRegistry.addPlugin(cc);
  -    cc.activateOptions();
  +//    ChainsawCentral cc = new ChainsawCentral();
  +//    pluginRegistry.addPlugin(cc);
  +//    cc.activateOptions();
       
   //    TODO this should also be fixed up, as VFS bits and pieces might not be built in an Ant build when they don't have all the VFS jars local
       try {
  @@ -443,6 +481,8 @@
       welcomePanel = new WelcomePanel();
   
       JToolBar tb = welcomePanel.getToolbar();
  +    
  +    
       tb.add(
         new SmallButton(
           new AbstractAction("Tutorial", new ImageIcon(ChainsawIcons.HELP)) {
  @@ -489,6 +529,9 @@
   
     private void ensureWelcomePanelVisible() {
         // ensure that the Welcome Panel is made visible
  +      if(!getTabbedPane().containsWelcomePanel()) {
  +          addWelcomePanel();
  +      }
         if(getTabbedPane().getSelectedComponent()!=welcomePanel) {
             getTabbedPane().setSelectedIndex(getTabbedPane().indexOfComponent(welcomePanel));
         }
  @@ -524,9 +567,6 @@
       event.saveSetting(LogUI.MAIN_WINDOW_WIDTH, getWidth());
       event.saveSetting(LogUI.MAIN_WINDOW_HEIGHT, getHeight());
   
  -    if (configURLToUse != null) {
  -      event.saveSetting(LogUI.CONFIG_FILE_TO_USE, configURLToUse.toString());
  -    }
     }
   
     /**
  @@ -536,40 +576,6 @@
      */
     public void activateViewer() {
       
  -      getSettingsManager().configure(
  -              new SettingsListener() {
  -                public void loadSettings(LoadSettingsEvent event) {
  -                  String configFile = event.getSetting(LogUI.CONFIG_FILE_TO_USE);
  -
  -                  //if both a config file are defined and a log4j.configuration property
  -                  // are set,
  -                  //don't use configFile's configuration
  -                  if (
  -                    (configFile != null) && !configFile.trim().equals("")
  -                      && (System.getProperty("log4j.configuration") == null)) {
  -                    try {
  -                      URL url = new URL(configFile);
  -                      OptionConverter.selectAndConfigure(
  -                        url, null, LogManager.getLoggerRepository());
  -
  -                      if (LogUI.this.getStatusBar() != null) {
  -                        MessageCenter.getInstance().getLogger().info(
  -                          "Configured Log4j using remembered URL :: " + url);
  -                      }
  -
  -                      LogUI.this.configURLToUse = url;
  -                    } catch (Exception e) {
  -                      MessageCenter.getInstance().getLogger().error(
  -                        "error occurred initializing log4j", e);
  -                    }
  -                  }
  -                }
  -
  -                public void saveSettings(SaveSettingsEvent event) {
  -                  //required because of SettingsListener interface..not used during load
  -                }
  -              });
  -
       this.pluginRegistry = LogManager.getLoggerRepository().getPluginRegistry();  
       initGUI();
   
  @@ -1316,16 +1322,7 @@
                 new Thread(
                   new Runnable() {
                     public void run() {
  -                    try {
  -                      OptionConverter.selectAndConfigure(
  -                        url, null, LogManager.getLoggerRepository());
  -                    } catch (Exception e) {
  -                      MessageCenter.getInstance().getLogger().error(
  -                        "Error initializing Log4j", e);
  -                    }
  -
  -                    LogManager.getLoggerRepository().getRootLogger()
  -                              .addAppender(handler);
  +                    loadConfigurationUsingPluginClassLoader(url);
   
                       receiversPanel.updateReceiverTreeInDispatchThread();
                     }
  @@ -1348,9 +1345,9 @@
     }
   
     void addWelcomePanel() {
  -    getTabbedPane().addANewTab(
  -      "Welcome", welcomePanel, new ImageIcon(ChainsawIcons.ABOUT),
  -      "Welcome/Help");
  +    getTabbedPane().insertTab(
  +      "Welcome",  new ImageIcon(ChainsawIcons.ABOUT),welcomePanel,
  +      "Welcome/Help", 0);
     }
   
     void removeWelcomePanel() {
  @@ -1590,9 +1587,7 @@
      *                    for content to show
      */
     public void showHelp(URL url) {
  -    removeWelcomePanel();
  -    addWelcomePanel();
  -
  +    ensureWelcomePanelVisible();
       //    TODO ensure the Welcome Panel is the selected tab
       getWelcomePanel().setURL(url);
     }
  @@ -1781,6 +1776,9 @@
   
       TabIconHandler iconHandler = new TabIconHandler(ident);
       thisPanel.addEventCountListener(iconHandler);
  +    
  +
  +
       tabbedPane.addChangeListener(iconHandler);
   
       PropertyChangeListener toolbarMenuUpdateListener =
  @@ -1864,6 +1862,45 @@
     }
   
     /**
  +   * Loads the log4j configuration file specified by the url, using
  +   * the PluginClassLoader instance as a TCCL, but only replacing it temporarily, with the original
  +   * TCCL being restored in a finally block to ensure consitency.
  +   * 
  +   * @param url
  +   */
  +    private void loadConfigurationUsingPluginClassLoader(final URL url) {
  +        ClassLoader classLoader = PluginClassLoaderFactory.getInstance().getClassLoader();
  +        ClassLoader previousTCCL = Thread.currentThread().getContextClassLoader();
  +        
  +        if(url!=null) {
  +            LogLog.info("Using '" + url.toExternalForm()+ "' for auto-configuration");
  +            try {
  +              // we temporarily swap the TCCL so that plugins can find resources
  +              Thread.currentThread().setContextClassLoader(classLoader);
  +              JoranConfigurator jc = new JoranConfigurator();
  +              jc.doConfigure(url, LogManager.getLoggerRepository());
  +              jc.logErrors();
  +            }finally{
  +                // now switch it back...
  +                Thread.currentThread().setContextClassLoader(previousTCCL);
  +            }
  +        }else {
  +            LogLog.info("auto-configuration file has not been provided");
  +        }
  +        ensureChainsawAppenderHandlerAdded();
  +    }
  +
  +    /**
  +     * Makes sure that the LoggerRepository has the ChainsawAppenderHandler
  +     * added to the root logger so Chainsaw can receive all the events.  
  +     */
  +    private void ensureChainsawAppenderHandlerAdded() {
  +        if(!LogManager.getLoggerRepository().getRootLogger().isAttached(handler)) {
  +            LogManager.getLoggerRepository().getRootLogger().addAppender(handler);
  +        }
  +    }
  +
  +/**
      * This class handles the recption of the Event batches and creates new
      * LogPanels if the identifier is not in use otherwise it ignores the event
      * batch.
  
  
  
  1.14      +114 -106  logging-log4j/src/java/org/apache/log4j/chainsaw/FileLoadAction.java
  
  Index: FileLoadAction.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/chainsaw/FileLoadAction.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- FileLoadAction.java	4 Aug 2004 03:48:12 -0000	1.13
  +++ FileLoadAction.java	2 Sep 2004 00:30:19 -0000	1.14
  @@ -35,121 +35,129 @@
   import org.apache.log4j.spi.Decoder;
   import org.apache.log4j.spi.LoggingEvent;
   
  -
   /**
  - * Allows the user to specify a particular file to open
  - * and import the events into a new tab.
  - *
  + * Allows the user to specify a particular file to open and import the events
  + * into a new tab.
  + * 
    * @author Paul Smith <ps...@apache.org>
    * @author Scott Deboy <sd...@apache.org>
  - *
  + *  
    */
   class FileLoadAction extends AbstractAction {
  -  private static final Logger LOG = Logger.getLogger(FileLoadAction.class);
  +    private static final Logger LOG = Logger.getLogger(FileLoadAction.class);
   
  -  /**
  -   * This action must have a reference to a LogUI
  -   * window so that it can append the events it loads
  -   *
  -   */
  -  Decoder decoder = null;
  -  private LogUI parent;
  -  private JFileChooser chooser = null;
  -  private boolean remoteURL = false;
  -
  -  public FileLoadAction(
  -    LogUI parent, Decoder decoder, String title, boolean isRemoteURL) {
  -    super(title);
  -    remoteURL = isRemoteURL;
  -    this.decoder = decoder;
  -    this.parent = parent;
  -  }
  -
  -  /*
  -   * When the user chooses the Load action,
  -   * a File chooser is presented to allow them to
  -   * find an XML file to load events from.
  -   *
  -   * Any events decoded from this file are added to
  -   * one of the tabs.
  -   * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
  -   */
  -  public void actionPerformed(ActionEvent e) {
  -    String name = "";
  -    URL url = null;
  -
  -    if (!remoteURL) {
  -      if (chooser == null) {
  -        chooser = new JFileChooser();
  -      }
  -
  -      chooser.setDialogTitle("Load Events from XML file...");
  -
  -      chooser.setAcceptAllFileFilterUsed(true);
  -
  -      chooser.setFileFilter(
  -        new FileFilter() {
  -          public boolean accept(File f) {
  -            return (f.getName().toLowerCase().endsWith(".xml")
  -            || f.isDirectory());
  -          }
  -
  -          public String getDescription() {
  -            return "XML files (*.xml)";
  -          }
  -        });
  -
  -      int i = chooser.showOpenDialog(parent);
  -      if(i != JFileChooser.APPROVE_OPTION) {
  -       return; 
  -      }
  -      File selectedFile = chooser.getSelectedFile();
  -
  -      
  -      try {
  -        url = selectedFile.toURL();
  -        name = selectedFile.getName();
  -      } catch (Exception ex) {
  -        // TODO: handle exception
  -      }
  -    } else {
  -      String urltext =
  -        JOptionPane.showInputDialog(
  -          parent,
  -          "<html>Please type in the <b>complete</b> URL to the remote XML source.</html>");
  -
  -      if (urltext != null) {
  -        try {
  -          url = new URL(urltext);
  -        } catch (Exception ex) {
  -          JOptionPane.showMessageDialog(
  -            parent, "'" + urltext + "' is not a valid URL.");
  -        }
  -      }
  +    /**
  +     * This action must have a reference to a LogUI window so that it can append
  +     * the events it loads
  +     *  
  +     */
  +    Decoder decoder = null;
  +
  +    private LogUI parent;
  +
  +    private JFileChooser chooser = null;
  +
  +    private boolean remoteURL = false;
  +
  +    public FileLoadAction(LogUI parent, Decoder decoder, String title,
  +            boolean isRemoteURL) {
  +        super(title);
  +        remoteURL = isRemoteURL;
  +        this.decoder = decoder;
  +        this.parent = parent;
       }
   
  -    if (url != null) {
  -      Map additionalProperties = new HashMap();
  -      additionalProperties.put(Constants.HOSTNAME_KEY, "file");
  -      additionalProperties.put(Constants.APPLICATION_KEY, name);
  -      decoder.setAdditionalProperties(additionalProperties);
  -
  -      final URL urlToUse = url;
  -      new Thread(
  -        new Runnable() {
  -          public void run() {
  +    /*
  +     * When the user chooses the Load action, a File chooser is presented to
  +     * allow them to find an XML file to load events from.
  +     * 
  +     * Any events decoded from this file are added to one of the tabs.
  +     * 
  +     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
  +     */
  +    public void actionPerformed(ActionEvent e) {
  +        String name = "";
  +        URL url = null;
  +
  +        if (!remoteURL) {
  +            if (chooser == null) {
  +                chooser = new JFileChooser();
  +            }
  +
  +            chooser.setDialogTitle("Load Events from XML file...");
  +
  +            chooser.setAcceptAllFileFilterUsed(true);
  +
  +            chooser.setFileFilter(new FileFilter() {
  +                public boolean accept(File f) {
  +                    return (f.getName().toLowerCase().endsWith(".xml") || f
  +                            .isDirectory());
  +                }
  +
  +                public String getDescription() {
  +                    return "XML files (*.xml)";
  +                }
  +            });
  +
  +            int i = chooser.showOpenDialog(parent);
  +            if (i != JFileChooser.APPROVE_OPTION) {
  +                return;
  +            }
  +            File selectedFile = chooser.getSelectedFile();
  +
               try {
  -              Vector events = decoder.decode(urlToUse);
  -              Iterator iter = events.iterator();
  -              while (iter.hasNext()) {
  -                  parent.handler.append((LoggingEvent)iter.next());
  -              }
  -            } catch (IOException e1) {
  -              // TODO Handle the error with a nice msg
  -              LOG.error(e1);
  +                url = selectedFile.toURL();
  +                name = selectedFile.getName();
  +            } catch (Exception ex) {
  +                // TODO: handle exception
  +            }
  +        } else {
  +            String urltext = JOptionPane
  +                    .showInputDialog(parent,
  +                            "<html>Please type in the <b>complete</b> URL to the remote XML source.</html>");
  +
  +            if (urltext != null) {
  +                try {
  +                    url = new URL(urltext);
  +                } catch (Exception ex) {
  +                    JOptionPane.showMessageDialog(parent, "'" + urltext
  +                            + "' is not a valid URL.");
  +                }
  +            }
  +        }
  +
  +        if (url != null) {
  +            importURL(parent.handler, decoder, name, url);
  +        }
  +    }
  +
  +    /**
  +     * Imports a URL into Chainsaw, by using the Decoder, and 
  +     * using the name value as the Application key which (usually) determines
  +     * the Tab name
  +     * @param name
  +     * @param url URL to import
  +     */
  +    public static void importURL(final ChainsawAppenderHandler handler, final Decoder decoder, String name, URL url) {
  +        Map additionalProperties = new HashMap();
  +        additionalProperties.put(Constants.HOSTNAME_KEY, "file");
  +        additionalProperties.put(Constants.APPLICATION_KEY, name);
  +        decoder.setAdditionalProperties(additionalProperties);
  +
  +        final URL urlToUse = url;
  +        new Thread(new Runnable() {
  +            public void run() {
  +                try {
  +                    Vector events = decoder.decode(urlToUse);
  +                    Iterator iter = events.iterator();
  +                    while (iter.hasNext()) {
  +                        handler.append((LoggingEvent) iter.next());
  +                    }
  +                } catch (IOException e1) {
  +                    // TODO Handle the error with a nice msg
  +                    LOG.error(e1);
  +                }
               }
  -          }
           }).start();
       }
  -  }
  -}
  +}
  \ No newline at end of file
  
  
  
  1.47      +0 -1      logging-log4j/src/java/org/apache/log4j/chainsaw/ChainsawToolBarAndMenus.java
  
  Index: ChainsawToolBarAndMenus.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/chainsaw/ChainsawToolBarAndMenus.java,v
  retrieving revision 1.46
  retrieving revision 1.47
  diff -u -r1.46 -r1.47
  --- ChainsawToolBarAndMenus.java	27 Jul 2004 07:06:58 -0000	1.46
  +++ ChainsawToolBarAndMenus.java	2 Sep 2004 00:30:19 -0000	1.47
  @@ -769,7 +769,6 @@
   
       if (logPanel == null) {
         activateLogPanelActions = false;
  -      logui.getStatusBar().clear();
         findField.setEnabled(false);
         findPanel.removeAll();
         findPanel.add(findField);
  
  
  
  1.41      +12 -0     logging-log4j/src/java/org/apache/log4j/chainsaw/help/release-notes.html
  
  Index: release-notes.html
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/chainsaw/help/release-notes.html,v
  retrieving revision 1.40
  retrieving revision 1.41
  diff -u -r1.40 -r1.41
  --- release-notes.html	19 Aug 2004 22:36:44 -0000	1.40
  +++ release-notes.html	2 Sep 2004 00:30:19 -0000	1.41
  @@ -9,6 +9,18 @@
   
   <h1>1.99.99</h2>
   
  +<h2>2 September 2004</h2>
  +<ul>
  +<li>Added Drag & Drop (rudimentary) support to Chainsaw.   You can drag any File to Chainsaw's 
  +  Tabbed Pane area and it will try to load it.  If there are no events in the file, not a lot happens...</li>
  +  
  +<li> Fixed a condition where loading an XML configuration file did not properly use the 
  +  correct classloader</li>
  +  
  +<li> Changed the way the Tabbed Pane functionality works, new tabs are added at the end and
  +  the new tab is not made active.</li>
  +</ul>
  +
   <h2>20 Aug 2004</h2>
   <ul>
   <li>Added DBReceiver to list of known Receivers, although not sure if it'll work</li>
  
  
  
  1.1                  logging-log4j/src/java/org/apache/log4j/chainsaw/dnd/FileDnDTarget.java
  
  Index: FileDnDTarget.java
  ===================================================================
  package org.apache.log4j.chainsaw.dnd;
  
  
  import org.apache.log4j.Logger;
  import java.awt.datatransfer.DataFlavor;
  import java.awt.Color;
  import java.awt.datatransfer.Transferable;
  import java.awt.dnd.DnDConstants;
  import java.awt.dnd.DropTarget;
  import java.awt.dnd.DropTargetDragEvent;
  import java.awt.dnd.DropTargetDropEvent;
  import java.awt.dnd.DropTargetEvent;
  import java.awt.dnd.DropTargetListener;
  import java.beans.PropertyChangeListener;
  import java.beans.PropertyChangeSupport;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  
  import javax.swing.BorderFactory;
  import javax.swing.JComponent;
  import javax.swing.colorchooser.ColorChooserComponentFactory;
  import javax.swing.event.EventListenerList;
  
  /**
   * This class provides all the functionality to work out when files are dragged onto
   * a particular JComponent instance, and then notifies listeners via
   * the standard PropertyChangesListener semantics to indicate that a list of 
   * files have been dropped onto the target.
   * 
   * If you wish to know whan the files have been dropped, subscribe to the "fileList" property change.
   * 
   * @author psmith
   *
   */
  public class FileDnDTarget implements DropTargetListener{
      /**
       * Logger for this class
       */
      private static final Logger LOG = Logger.getLogger(FileDnDTarget.class);
  
      protected int acceptableActions = DnDConstants.ACTION_COPY;
  
      private DropTarget dropTarget;
      private List fileList;
  
      private JComponent guiTarget;
      private Map dropTargets = new HashMap();
      
      
      private PropertyChangeSupport propertySupport = new PropertyChangeSupport(this);
      /**
       * 
       */
      public FileDnDTarget(JComponent c) {
          this.guiTarget = c;
          dropTarget = new DropTarget(this.guiTarget, this);
      }
      
      public void addDropTargetToComponent(JComponent c){
          dropTargets.put(c, new DropTarget(c, this));
      }
      
      /**
       * @param listener
       */
      public void addPropertyChangeListener(PropertyChangeListener listener) {
          propertySupport.addPropertyChangeListener(listener);
      }
      /**
       * @param propertyName
       * @param listener
       */
      public void addPropertyChangeListener(String propertyName,
              PropertyChangeListener listener) {
          propertySupport.addPropertyChangeListener(propertyName, listener);
      }
  
      /**
       * 
       */
      private void decorateComponent() {
  //        TODO work out a better way of decorating a component
          guiTarget.setBorder(BorderFactory.createLineBorder(Color.black));
      }
  
  
      public void dragEnter(DropTargetDragEvent e) {
          //LOG.debug(dtde);
          if (isDragOk(e) == false) {
              e.rejectDrag();
              return;
          }
          decorateComponent();
  
          e.acceptDrag(acceptableActions);
      }
  
  
      public void dragExit(DropTargetEvent dte) {
          removeComponentDecoration();
      }
  
  
      public void dragOver(DropTargetDragEvent e) {
          //LOG.debug(dtde);
  
          if (isDragOk(e) == false) {
              e.rejectDrag();
              return;
          }
          e.acceptDrag(acceptableActions);
      }
  
      public void drop(DropTargetDropEvent dtde) {
          Transferable transferable = dtde.getTransferable();
          LOG.debug(transferable);
          dtde.acceptDrop(acceptableActions);
          try {
              List list = (List)transferable.getTransferData(DataFlavor.javaFileListFlavor);
              LOG.debug(list);
              setFileList(list);
              dtde.getDropTargetContext().dropComplete(true);
              removeComponentDecoration();
  
          } catch (Exception e) {
              LOG.error("Error with DnD", e);
          }
          
      }
  
      public void dropActionChanged(DropTargetDragEvent dtde) {
          //LOG.debug(dtde);
      }
      /**
       * @return Returns the fileList.
       */
      public final List getFileList() {
          return fileList;
      }
  
      private boolean isDragOk(DropTargetDragEvent e) {
      	DataFlavor[] flavors = new DataFlavor[] { DataFlavor.javaFileListFlavor };
      	DataFlavor chosen = null;
      	for (int i = 0; i < flavors.length; i++) {
      		if (e.isDataFlavorSupported(flavors[i])) {
      			chosen = flavors[i];
      			break;
      		}
      	}
      	/*
      	 * the src does not support any of the StringTransferable flavors
      	 */
      	if (chosen == null) {
      		return false;
      	}
      	// the actions specified when the source
      	// created the DragGestureRecognizer
      	int sa = e.getSourceActions();
      
      	// we're saying that these actions are necessary
      	if ((sa & acceptableActions) == 0)
      		return false;
      	return true;
      }
  
      /**
       * 
       */
      private void removeComponentDecoration() {
          this.guiTarget.setBorder(null);
      }
      /**
       * @param listener
       */
      public void removePropertyChangeListener(PropertyChangeListener listener) {
          propertySupport.removePropertyChangeListener(listener);
      }
      /**
       * @param propertyName
       * @param listener
       */
      public void removePropertyChangeListener(String propertyName,
              PropertyChangeListener listener) {
          propertySupport.removePropertyChangeListener(propertyName, listener);
      }
      
      /**
       * @param fileList The fileList to set.
       */
      private  final void setFileList(List fileList) {
          Object oldValue = this.fileList;
          this.fileList = fileList;
          propertySupport.firePropertyChange("fileList", oldValue, this.fileList);
      }
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org