Hi all, This is probably fixed in the latest Chainsaw, but I thought I'd forward this patch against 1.2.8 anyway. In the two attached files, the only change is to allow one to pass in the Action object that is registered with close events. I needed this functionality to run Chainsaw in-VM with my application. BTW, will there be a 1.2.9 release including the Chainsaw changes, or will I have to wait for 1.3? - Matt
/* * Copyright (C) The Apache Software Foundation. All rights reserved. * * 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. */ package org.apache.log4j.chainsaw;
import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.IOException; import java.util.Properties; import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTable; import javax.swing.ListSelectionModel; import org.apache.log4j.Category; import org.apache.log4j.PropertyConfigurator; /** * The main application. * * @author <a href="mailto:[EMAIL PROTECTED]">Oliver Burn</a> */ public class Main extends JFrame { /** the default port number to listen on **/ private static final int DEFAULT_PORT = 4445; /** name of property for port name **/ public static final String PORT_PROP_NAME = "chainsaw.port"; /** use to log messages **/ private static final Category LOG = Category.getInstance(Main.class); /** * Creates a new <code>Main</code> instance. */ private Main() { this(ExitAction.INSTANCE); } /** * Creates a new <code>Main</code> instance. */ public Main(final Action exitAction) { super("CHAINSAW - Log4J Log Viewer"); // create the all important model final MyTableModel model = new MyTableModel(); //Create the menu bar. final JMenuBar menuBar = new JMenuBar(); setJMenuBar(menuBar); final JMenu menu = new JMenu("File"); menuBar.add(menu); try { final LoadXMLAction lxa = new LoadXMLAction(this, model); final JMenuItem loadMenuItem = new JMenuItem("Load file..."); menu.add(loadMenuItem); loadMenuItem.addActionListener(lxa); } catch (NoClassDefFoundError e) { LOG.info("Missing classes for XML parser", e); JOptionPane.showMessageDialog( this, "XML parser not in classpath - unable to load XML events.", "CHAINSAW", JOptionPane.ERROR_MESSAGE); } catch (Exception e) { LOG.info("Unable to create the action to load XML files", e); JOptionPane.showMessageDialog( this, "Unable to create a XML parser - unable to load XML events.", "CHAINSAW", JOptionPane.ERROR_MESSAGE); } final JMenuItem exitMenuItem = new JMenuItem("Exit"); menu.add(exitMenuItem); exitMenuItem.addActionListener(exitAction); // Add control panel final ControlPanel cp = new ControlPanel(model, exitAction); getContentPane().add(cp, BorderLayout.NORTH); // Create the table final JTable table = new JTable(model); table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); final JScrollPane scrollPane = new JScrollPane(table); scrollPane.setBorder(BorderFactory.createTitledBorder("Events: ")); scrollPane.setPreferredSize(new Dimension(900, 300)); // Create the details final JPanel details = new DetailPanel(table, model); details.setPreferredSize(new Dimension(900, 300)); // Add the table and stack trace into a splitter final JSplitPane jsp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, scrollPane, details); getContentPane().add(jsp, BorderLayout.CENTER); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent aEvent) { exitAction.actionPerformed(null); } }); pack(); setVisible(true); setupReceiver(model); } /** * Setup recieving messages. * * @param aModel a <code>MyTableModel</code> value */ private void setupReceiver(MyTableModel aModel) { int port = DEFAULT_PORT; final String strRep = System.getProperty(PORT_PROP_NAME); if (strRep != null) { try { port = Integer.parseInt(strRep); } catch (NumberFormatException nfe) { LOG.fatal("Unable to parse " + PORT_PROP_NAME + " property with value " + strRep + "."); JOptionPane.showMessageDialog( this, "Unable to parse port number from '" + strRep + "', quitting.", "CHAINSAW", JOptionPane.ERROR_MESSAGE); System.exit(1); } } try { final LoggingReceiver lr = new LoggingReceiver(aModel, port); lr.start(); } catch (IOException e) { LOG.fatal("Unable to connect to socket server, quiting", e); JOptionPane.showMessageDialog( this, "Unable to create socket on port " + port + ", quitting.", "CHAINSAW", JOptionPane.ERROR_MESSAGE); System.exit(1); } } //////////////////////////////////////////////////////////////////////////// // static methods //////////////////////////////////////////////////////////////////////////// /** initialise log4j **/ private static void initLog4J() { final Properties props = new Properties(); props.setProperty("log4j.rootCategory", "DEBUG, A1"); props.setProperty("log4j.appender.A1", "org.apache.log4j.ConsoleAppender"); props.setProperty("log4j.appender.A1.layout", "org.apache.log4j.TTCCLayout"); PropertyConfigurator.configure(props); } /** * The main method. * * @param aArgs ignored */ public static void main(String[] aArgs) { initLog4J(); new Main(); } }
/* * Copyright (C) The Apache Software Foundation. All rights reserved. * * 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. */ package org.apache.log4j.chainsaw; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import org.apache.log4j.Category; import org.apache.log4j.Priority; /** * Represents the controls for filtering, pausing, exiting, etc. * * @author <a href="mailto:[EMAIL PROTECTED]">Oliver Burn</a> */ class ControlPanel extends JPanel { /** use the log messages **/ private static final Category LOG = Category.getInstance(ControlPanel.class); /** * Creates a new <code>ControlPanel</code> instance. * * @param aModel the model to control */ ControlPanel(final MyTableModel aModel, Action exitAction) { setBorder(BorderFactory.createTitledBorder("Controls: ")); final GridBagLayout gridbag = new GridBagLayout(); final GridBagConstraints c = new GridBagConstraints(); setLayout(gridbag); // Pad everything c.ipadx = 5; c.ipady = 5; // Add the 1st column of labels c.gridx = 0; c.anchor = GridBagConstraints.EAST; c.gridy = 0; JLabel label = new JLabel("Filter Level:"); gridbag.setConstraints(label, c); add(label); c.gridy++; label = new JLabel("Filter Thread:"); gridbag.setConstraints(label, c); add(label); c.gridy++; label = new JLabel("Filter Category:"); gridbag.setConstraints(label, c); add(label); c.gridy++; label = new JLabel("Filter NDC:"); gridbag.setConstraints(label, c); add(label); c.gridy++; label = new JLabel("Filter Message:"); gridbag.setConstraints(label, c); add(label); // Add the 2nd column of filters c.weightx = 1; //c.weighty = 1; c.gridx = 1; c.anchor = GridBagConstraints.WEST; 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); priorities.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent aEvent) { aModel.setPriorityFilter( (Priority) priorities.getSelectedItem()); } }); c.fill = GridBagConstraints.HORIZONTAL; 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) { aModel.setThreadFilter(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) { aModel.setCategoryFilter(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) { aModel.setNDCFilter(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) { aModel.setMessageFilter(msgField.getText()); } }); gridbag.setConstraints(msgField, c); add(msgField); // Add the 3rd column of buttons c.weightx = 0; c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.EAST; c.gridx = 2; c.gridy = 0; final JButton exitButton = new JButton("Exit"); exitButton.setMnemonic('x'); exitButton.addActionListener(exitAction); gridbag.setConstraints(exitButton, c); add(exitButton); c.gridy++; final JButton clearButton = new JButton("Clear"); clearButton.setMnemonic('c'); clearButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent aEvent) { aModel.clear(); } }); gridbag.setConstraints(clearButton, c); add(clearButton); c.gridy++; final JButton toggleButton = new JButton("Pause"); toggleButton.setMnemonic('p'); toggleButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent aEvent) { aModel.toggle(); toggleButton.setText( aModel.isPaused() ? "Resume" : "Pause"); } }); gridbag.setConstraints(toggleButton, c); add(toggleButton); } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]