psmith 2003/09/03 22:45:16
Modified: src/java/org/apache/log4j/chainsaw/layout
EventDetailLayout.java
src/java/org/apache/log4j/chainsaw LogUI.java
Added: src/java/org/apache/log4j/chainsaw/layout
DefaultLayoutFactory.java LayoutEditorPane.java
Log:
added support for a PatternLayout Editor dialog which
edits and sets the Layout used in the Event detail pane.
Allows user to Edit pattern text and shows a running preview
of the result in a preview pane as you type.
Refactored the loading of the default html pattern text into
a separate class.
Revision Changes Path
1.2 +7 -52
jakarta-log4j/src/java/org/apache/log4j/chainsaw/layout/EventDetailLayout.java
Index: EventDetailLayout.java
===================================================================
RCS file:
/home/cvs/jakarta-log4j/src/java/org/apache/log4j/chainsaw/layout/EventDetailLayout.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- EventDetailLayout.java 4 Sep 2003 02:30:28 -0000 1.1
+++ EventDetailLayout.java 4 Sep 2003 05:45:16 -0000 1.2
@@ -52,80 +52,35 @@
import org.apache.log4j.Layout;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
-import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.spi.LocationInfo;
import org.apache.log4j.spi.LoggingEvent;
-import java.io.BufferedReader;
import java.io.IOException;
-import java.io.InputStreamReader;
import java.io.Writer;
-import java.net.URL;
-
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
-import javax.swing.text.html.HTMLEditorKit;
-
/**
* This layout is used for formatting HTML text for use inside
* the Chainsaw Event Detail Panel, and the tooltip used
- * when mouse-over on a particular log event row
+ * when mouse-over on a particular log event row.
+ *
+ * It relies an an internal PatternLayout to accomplish this, but ensures HTML
characters
+ * from any LoggingEvent are escaped first.
*
* @author Paul Smith <[EMAIL PROTECTED]>
*/
public class EventDetailLayout extends Layout {
- private PatternLayout patternLayout =
- new PatternLayout(PatternLayout.TTCC_CONVERSION_PATTERN);
+ private PatternLayout patternLayout = new PatternLayout();
public EventDetailLayout() {
- URL defaultLayoutURL =
- this.getClass().getClassLoader().getResource(
- "org/apache/log4j/chainsaw/layout/DefaultDetailLayout.html");
-
- if (defaultLayoutURL == null) {
- LogLog.warn(
- "Could not locate the default Layout for Event Details and Tooltips");
- } else {
- HTMLEditorKit kit = new HTMLEditorKit();
-
- try {
- StringBuffer content = new StringBuffer();
- BufferedReader reader = null;
-
- try {
- reader =
- new BufferedReader(
- new InputStreamReader(defaultLayoutURL.openStream()));
-
- String line = "";
-
- while ((line = reader.readLine()) != null) {
- content.append(line);
- }
- } finally {
- if (reader != null) {
- reader.close();
- }
- }
-
- if (content != null) {
- LogLog.debug("Loaded layout content:\n" + content);
- patternLayout.setConversionPattern(content.toString());
- } else {
- LogLog.warn("No Layout content retrieved, using default");
- }
- } catch (Exception e) {
- LogLog.error("Failed to read in the Layout", e);
- }
- }
}
- public void setConverionPatter(String conversionPatter) {
- patternLayout.setConversionPattern(conversionPatter);
+ public void setConversionPattern(String conversionPattern) {
+ patternLayout.setConversionPattern(conversionPattern);
}
public String getConversionPattern() {
1.1
jakarta-log4j/src/java/org/apache/log4j/chainsaw/layout/DefaultLayoutFactory.java
Index: DefaultLayoutFactory.java
===================================================================
/*
* ============================================================================
* The Apache Software License, Version 1.1
* ============================================================================
*
* 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.layout;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.helpers.LogLog;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
/**
* Factory class to load and cache Layout information from resources.
*
* @author Paul Smith <[EMAIL PROTECTED]>
*/
public class DefaultLayoutFactory {
private static String defaultPatternLayout = null;
private DefaultLayoutFactory() {
}
public static String getDefaultPatternLayout() {
if (defaultPatternLayout == null) {
StringBuffer content = new StringBuffer();
URL defaultLayoutURL =
DefaultLayoutFactory.class.getClassLoader().getResource(
"org/apache/log4j/chainsaw/layout/DefaultDetailLayout.html");
if (defaultLayoutURL == null) {
LogLog.warn(
"Could not locate the default Layout for Event Details and Tooltips");
} else {
try {
BufferedReader reader = null;
try {
reader =
new BufferedReader(
new InputStreamReader(defaultLayoutURL.openStream()));
String line = "";
while ((line = reader.readLine()) != null) {
content.append(line).append("\n");
}
} finally {
if (reader != null) {
reader.close();
}
}
} catch (Exception e) {
content = new StringBuffer(PatternLayout.TTCC_CONVERSION_PATTERN);
}
defaultPatternLayout = content.toString();
}
}
return defaultPatternLayout;
}
}
1.1
jakarta-log4j/src/java/org/apache/log4j/chainsaw/layout/LayoutEditorPane.java
Index: LayoutEditorPane.java
===================================================================
/*
* ============================================================================
* The Apache Software License, Version 1.1
* ============================================================================
*
* 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.layout;
import org.apache.log4j.Logger;
import org.apache.log4j.chainsaw.ChainsawConstants;
import org.apache.log4j.chainsaw.icons.ChainsawIcons;
import org.apache.log4j.spi.LocationInfo;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.ThrowableInformation;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import java.util.Hashtable;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
/**
* An editor Pane that allows a user to Edit a Pattern Layout and preview the output
it would
* generate with an example LoggingEvent
*
* @author Paul Smith <[EMAIL PROTECTED]>
*
*/
public final class LayoutEditorPane extends JPanel {
private final Action copyAction;
private final Action cutAction;
private final JToolBar editorToolbar = new JToolBar();
private final JToolBar okCancelToolbar = new JToolBar();
private final JButton okButton = new JButton("Ok");
private final JButton cancelButton = new JButton("Cancel");
// private final JButton applyButton = new JButton();
private final JEditorPane patternEditor = new JEditorPane("text/plain", "");
private final JEditorPane previewer =
new JEditorPane(ChainsawConstants.DETAIL_CONTENT_TYPE, "");
private final JScrollPane patternEditorScroll =
new JScrollPane(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
private final JScrollPane previewEditorScroll =
new JScrollPane(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
private LoggingEvent event;
private EventDetailLayout layout = new EventDetailLayout();
/**
*
*/
public LayoutEditorPane() {
super();
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
createEvent();
copyAction = createCopyAction();
cutAction = createCutAction();
initComponents();
setupListeners();
}
/**
* @return
*/
private Action createCutAction() {
final Action action =
new AbstractAction("Cut", ChainsawIcons.ICON_CUT) {
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
};
action.setEnabled(false);
return action;
}
/**
* @return
*/
private Action createCopyAction() {
final Action action =
new AbstractAction("Copy", ChainsawIcons.ICON_COPY) {
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
};
action.setEnabled(false);
return action;
}
/**
*
*/
private void setupListeners() {
patternEditor.getDocument().addDocumentListener(
new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
updatePreview();
}
public void insertUpdate(DocumentEvent e) {
updatePreview();
}
public void removeUpdate(DocumentEvent e) {
updatePreview();
}
});
patternEditor.addCaretListener(
new CaretListener() {
public void caretUpdate(CaretEvent e) {
updateTextActions(e.getMark() != e.getDot());
}
});
}
private void updatePreview() {
String pattern = patternEditor.getText();
layout.setConversionPattern(pattern);
previewer.setText(layout.format(event));
}
/**
*
*/
private void updateTextActions(boolean enabled) {
cutAction.setEnabled(enabled);
copyAction.setEnabled(enabled);
}
/**
*
*/
private void createEvent() {
Hashtable hashTable = new Hashtable();
hashTable.put("key1", "val1");
hashTable.put("key2", "val2");
hashTable.put("key3", "val3");
LocationInfo li =
new LocationInfo(
"myfile.java", "com.mycompany.util.MyClass", "myMethod", "321");
ThrowableInformation tsr = new ThrowableInformation(new Exception());
event =
new LoggingEvent(
"com.mycompany.mylogger", Logger.getLogger("com.mycompany.mylogger"),
new Date().getTime(), org.apache.log4j.Level.DEBUG, "Thread-1",
"The quick brown fox jumped over the lazy dog", "NDC string", hashTable,
tsr.getThrowableStrRep(), li, hashTable);
}
/**
*
*/
private void initComponents() {
editorToolbar.setFloatable(false);
okCancelToolbar.setFloatable(false);
okButton.setToolTipText("Accepts the current Pattern layout and will apply it to
the Log Panel");
cancelButton.setToolTipText("Closes this dialog and discards your changes");
previewer.setEditable(false);
patternEditor.setPreferredSize(new Dimension(240, 240));
patternEditor.setMaximumSize(new Dimension(320, 240));
previewer.setPreferredSize(new Dimension(360, 240));
patternEditorScroll.setViewportView(patternEditor);
previewEditorScroll.setViewportView(previewer);
patternEditor.setToolTipText("Edit the Pattern here");
previewer.setToolTipText(
"The result of the layout of the pattern is shown here");
patternEditorScroll.setBorder(
BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(), "Pattern Editor"));
previewEditorScroll.setBorder(
BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(), "Pattern Preview"));
// editorToolbar.add(new JButton(copyAction));
// editorToolbar.add(new JButton(cutAction));
editorToolbar.add(Box.createHorizontalGlue());
okCancelToolbar.add(Box.createHorizontalGlue());
okCancelToolbar.add(okButton);
okCancelToolbar.addSeparator();
okCancelToolbar.add(cancelButton);
// okCancelToolbar.addSeparator();
// okCancelToolbar.add(applyButton);
add(editorToolbar);
add(patternEditorScroll);
add(previewEditorScroll);
add(okCancelToolbar);
}
public void setConversionPattern(String pattern) {
patternEditor.setText(pattern);
}
public String getConversionPattern() {
return patternEditor.getText();
}
public void addOkActionListener(ActionListener l) {
okButton.addActionListener(l);
}
public void addCancelActionListener(ActionListener l) {
cancelButton.addActionListener(l);
}
public static void main(String[] args) {
JDialog dialog = new JDialog((Frame) null, "Pattern Editor");
dialog.getContentPane().add(new LayoutEditorPane());
dialog.setResizable(true);
dialog.setDefaultCloseOperation(JDialog.EXIT_ON_CLOSE);
// dialog.pack();
dialog.setSize(new Dimension(640, 480));
dialog.setVisible(true);
}
}
1.19 +78 -1 jakarta-log4j/src/java/org/apache/log4j/chainsaw/LogUI.java
Index: LogUI.java
===================================================================
RCS file: /home/cvs/jakarta-log4j/src/java/org/apache/log4j/chainsaw/LogUI.java,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- LogUI.java 4 Sep 2003 02:30:28 -0000 1.18
+++ LogUI.java 4 Sep 2003 05:45:16 -0000 1.19
@@ -52,10 +52,13 @@
import org.apache.log4j.Layout;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
+import org.apache.log4j.PatternLayout;
import org.apache.log4j.Priority;
import org.apache.log4j.UtilLoggingLevel;
import org.apache.log4j.chainsaw.icons.ChainsawIcons;
+import org.apache.log4j.chainsaw.layout.DefaultLayoutFactory;
import org.apache.log4j.chainsaw.layout.EventDetailLayout;
+import org.apache.log4j.chainsaw.layout.LayoutEditorPane;
import org.apache.log4j.chainsaw.prefs.LoadSettingsEvent;
import org.apache.log4j.chainsaw.prefs.SaveSettingsEvent;
import org.apache.log4j.chainsaw.prefs.SettingsListener;
@@ -1227,6 +1230,11 @@
public LogPanel(final String ident, String eventType) {
identifier = ident;
+ setDetailPaneConversionPattern(
+ DefaultLayoutFactory.getDefaultPatternLayout());
+ ((EventDetailLayout) toolTipLayout).setConversionPattern(
+ DefaultLayoutFactory.getDefaultPatternLayout());
+
Map map = new HashMap();
entryMap.put(ident, map);
@@ -1586,11 +1594,45 @@
final JToolBar detailToolbar = new JToolBar(JToolBar.HORIZONTAL);
detailToolbar.setFloatable(false);
+ final LayoutEditorPane layoutEditorPane = new LayoutEditorPane();
+ final JDialog layoutEditorDialog =
+ new JDialog(LogUI.this, "Pattern Editor");
+ layoutEditorDialog.getContentPane().add(layoutEditorPane);
+ layoutEditorDialog.setSize(640, 480);
+
+ layoutEditorPane.addCancelActionListener(
+ new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ layoutEditorDialog.setVisible(false);
+ }
+ });
+
+ layoutEditorPane.addOkActionListener(
+ new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ setDetailPaneConversionPattern(
+ layoutEditorPane.getConversionPattern());
+ layoutEditorDialog.setVisible(false);
+ }
+ });
+
Action editDetailAction =
new AbstractAction(
"Edit...", new ImageIcon(ChainsawIcons.ICON_EDIT_RECEIVER)) {
public void actionPerformed(ActionEvent e) {
- // TODO Auto-generated method stub
+ layoutEditorPane.setConversionPattern(
+ getDetailPaneConversionPattern());
+
+ Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
+ Point p =
+ new Point(
+ ((int) ((size.getWidth() / 2)
+ - (layoutEditorDialog.getSize().getWidth() / 2))),
+ ((int) ((size.getHeight() / 2)
+ - (layoutEditorDialog.getSize().getHeight() / 2))));
+ layoutEditorDialog.setLocation(p);
+
+ layoutEditorDialog.setVisible(true);
}
};
@@ -1606,6 +1648,32 @@
// detailToolbar.add(Box.createHorizontalStrut(5));
detailPanel.add(detailToolbar, BorderLayout.NORTH);
+ JPopupMenu editDetailPopupMenu = new JPopupMenu();
+ editDetailPopupMenu.add(editDetailAction);
+ editDetailPopupMenu.addSeparator();
+
+ editDetailPopupMenu.add(
+ new AbstractAction("Set to Default Layout") {
+ public void actionPerformed(ActionEvent e) {
+ setDetailPaneConversionPattern(
+ DefaultLayoutFactory.getDefaultPatternLayout());
+ }
+ });
+
+ editDetailPopupMenu.addSeparator();
+
+ editDetailPopupMenu.add(
+ new AbstractAction("Set to TCCLayout") {
+ public void actionPerformed(ActionEvent e) {
+ setDetailPaneConversionPattern(
+ PatternLayout.TTCC_CONVERSION_PATTERN);
+ }
+ });
+
+ PopupListener editDetailPopupListener =
+ new PopupListener(editDetailPopupMenu);
+ detail.addMouseListener(editDetailPopupListener);
+
lowerPanel =
new JSplitPane(
JSplitPane.VERTICAL_SPLIT, eventsAndStatusPanel, detailPanel);
@@ -1976,6 +2044,15 @@
table.getSelectedRow() + 1, table.getModel().getRowCount());
}
});
+ }
+
+ void setDetailPaneConversionPattern(String conversionPattern) {
+ ((EventDetailLayout) detailPaneLayout).setConversionPattern(
+ conversionPattern);
+ }
+
+ String getDetailPaneConversionPattern() {
+ return ((EventDetailLayout) detailPaneLayout).getConversionPattern();
}
void showPreferences() {
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]