Added multi-select capability to event table and 'copy selection' context menu item (multi-select by holding down alt key while selecting rows) New 'add to find field' context menu option Simplified context menu (removed scroll to bottom/top, moved dock option to bottom) Updated logic determining value for a specific cell
Project: http://git-wip-us.apache.org/repos/asf/logging-chainsaw/repo Commit: http://git-wip-us.apache.org/repos/asf/logging-chainsaw/commit/9f01847a Tree: http://git-wip-us.apache.org/repos/asf/logging-chainsaw/tree/9f01847a Diff: http://git-wip-us.apache.org/repos/asf/logging-chainsaw/diff/9f01847a Branch: refs/heads/master Commit: 9f01847ae19f6ae850b6c7f4baf5a71c9dcd8361 Parents: cf258ed Author: Scott Deboy <[email protected]> Authored: Sat Nov 6 23:42:31 2010 +0000 Committer: Scott Deboy <[email protected]> Committed: Sat Nov 6 23:42:31 2010 +0000 ---------------------------------------------------------------------- .../org/apache/log4j/chainsaw/LogPanel.java | 399 ++++++++++--------- .../log4j/chainsaw/LoggerNameTreePanel.java | 55 ++- .../log4j/chainsaw/TableColorizingRenderer.java | 5 +- .../apache/log4j/chainsaw/color/ColorPanel.java | 16 +- .../log4j/chainsaw/help/release-notes.html | 1 + 5 files changed, 267 insertions(+), 209 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/logging-chainsaw/blob/9f01847a/src/main/java/org/apache/log4j/chainsaw/LogPanel.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/log4j/chainsaw/LogPanel.java b/src/main/java/org/apache/log4j/chainsaw/LogPanel.java index edeec44..70d54da 100644 --- a/src/main/java/org/apache/log4j/chainsaw/LogPanel.java +++ b/src/main/java/org/apache/log4j/chainsaw/LogPanel.java @@ -40,6 +40,7 @@ import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; import java.awt.event.MouseMotionAdapter; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; @@ -57,9 +58,9 @@ import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.text.DateFormat; import java.text.NumberFormat; -import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Date; import java.util.Enumeration; import java.util.EventObject; import java.util.HashMap; @@ -79,7 +80,6 @@ import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; import javax.swing.ComboBoxEditor; -import javax.swing.ComboBoxModel; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBoxMenuItem; @@ -206,6 +206,7 @@ import com.thoughtworks.xstream.io.xml.DomDriver; * */ public class LogPanel extends DockablePanel implements EventBatchListener, Profileable { + private static final DateFormat TIMESTAMP_DATE_FORMAT = new SimpleDateFormat(Constants.TIMESTAMP_RULE_FORMAT); private static final double DEFAULT_DETAIL_SPLIT_LOCATION = 0.71d; private static final double DEFAULT_LOG_TREE_SPLIT_LOCATION = 0.2d; private final String identifier; @@ -247,7 +248,6 @@ public class LogPanel extends DockablePanel implements EventBatchListener, Profi static final String COLORS_EXTENSION = ".colors"; private static final int LOG_PANEL_SERIALIZATION_VERSION_NUMBER = 2; //increment when format changes private int previousLastIndex = -1; - private final DateFormat timestampExpressionFormat = new SimpleDateFormat(Constants.TIMESTAMP_RULE_FORMAT); private final Logger logger = LogManager.getLogger(LogPanel.class); private AutoFilterComboBox filterCombo; private AutoFilterComboBox findCombo; @@ -408,27 +408,6 @@ public class LogPanel extends DockablePanel implements EventBatchListener, Profi }); menuItemLoggerTree.setIcon(new ImageIcon(ChainsawIcons.WINDOW_ICON)); - final JMenuItem menuItemScrollToTop = new JMenuItem("Scroll to top"); - menuItemScrollToTop.addActionListener( - new ActionListener() { - public void actionPerformed(ActionEvent evt) - { - scrollToTop(); - } - }); - final JCheckBoxMenuItem menuItemScrollBottom = - new JCheckBoxMenuItem("Scroll to bottom"); - menuItemScrollBottom.addActionListener( - new ActionListener() { - public void actionPerformed(ActionEvent evt) { - preferenceModel.setScrollToBottom(menuItemScrollBottom.isSelected()); - } - }); - menuItemScrollBottom.setSelected(isScrollToBottom()); - - menuItemScrollBottom.setIcon( - new ImageIcon(ChainsawIcons.SCROLL_TO_BOTTOM)); - final JCheckBoxMenuItem menuItemToggleDetails = new JCheckBoxMenuItem("Show Detail Pane"); menuItemToggleDetails.addActionListener( @@ -644,18 +623,6 @@ public class LogPanel extends DockablePanel implements EventBatchListener, Profi }); preferenceModel.addPropertyChangeListener( - "scrollToBottom", - new PropertyChangeListener() { - public void propertyChange(PropertyChangeEvent evt) { - boolean value = ((Boolean) evt.getNewValue()).booleanValue(); - menuItemScrollBottom.setSelected(value); - if (value) { - scrollToBottom(); - } - } - }); - - preferenceModel.addPropertyChangeListener( "detailPaneVisible", new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { @@ -1562,26 +1529,7 @@ public class LogPanel extends DockablePanel implements EventBatchListener, Profi int column = currentTable.columnAtPoint(currentPoint); int row = currentTable.rowAtPoint(currentPoint); String colName = currentTable.getColumnName(column).toUpperCase(); - String value = ""; - - if (colName.equalsIgnoreCase(ChainsawConstants.TIMESTAMP_COL_NAME)) { - try { - value = timestampExpressionFormat.parse(currentTable.getValueAt(row, column).toString()).toString(); - } catch (ParseException e) { - e.printStackTrace(); - } - } else { - Object o = table.getValueAt(row, column); - - if (o != null) { - if (o instanceof String[] && ((String[])o).length > 0) { - value = ((String[]) o)[0]; - operator = "~="; - } else { - value = o.toString(); - } - } - } + String value = getValueOf(row, column); if (columnNameKeywordMap.containsKey(colName)) { filterText.setText( @@ -1604,32 +1552,41 @@ public class LogPanel extends DockablePanel implements EventBatchListener, Profi String operator = "=="; int column = currentTable.columnAtPoint(currentPoint); int row = currentTable.rowAtPoint(currentPoint); + String value = getValueOf(row, column); String colName = currentTable.getColumnName(column).toUpperCase(); - String value = ""; - if (colName.equalsIgnoreCase(ChainsawConstants.TIMESTAMP_COL_NAME)) { - JComponent comp = - (JComponent) currentTable.getCellRenderer(row, column); + if (columnNameKeywordMap.containsKey(colName)) { + filterText.setText( + filterText.getText() + " && " + + columnNameKeywordMap.get(colName).toString() + " " + + operator + " '" + value + "'"); + } - if (comp instanceof JLabel) { - value = ((JLabel) comp).getText(); - } - } else { - Object o = currentTable.getValueAt(row, column); + } + } + }); + } + } - if (o instanceof String[] && ((String[])o).length > 0) { - value = ((String[]) o)[0]; - operator = "~="; - } else { - value = o.toString(); - } - } + class DefineAddCustomFind extends JMenuItem { + public DefineAddCustomFind() { + super("Add value under pointer to 'find' field"); + addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent evt) { + if (currentPoint != null) { + String operator = "=="; + int column = currentTable.columnAtPoint(currentPoint); + int row = currentTable.rowAtPoint(currentPoint); + String value = getValueOf(row, column); + String colName = currentTable.getColumnName(column).toUpperCase(); if (columnNameKeywordMap.containsKey(colName)) { - filterText.setText( - filterText.getText() + " && " + findCombo.setSelectedItem( + findText.getText() + " && " + columnNameKeywordMap.get(colName).toString() + " " + operator + " '" + value + "'"); + findNext(); } } } @@ -1648,24 +1605,7 @@ public class LogPanel extends DockablePanel implements EventBatchListener, Profi int column = currentTable.columnAtPoint(currentPoint); int row = currentTable.rowAtPoint(currentPoint); String colName = currentTable.getColumnName(column).toUpperCase(); - String value = ""; - - if (colName.equalsIgnoreCase(ChainsawConstants.TIMESTAMP_COL_NAME)) { - JComponent comp = - (JComponent) currentTable.getCellRenderer(row, column); - - if (comp instanceof JLabel) { - value = ((JLabel) comp).getText(); - } - } else { - Object o = currentTable.getValueAt(row, column); - - if (o instanceof String[] && ((String[])o).length > 0) { - value = ((String[]) o)[0]; - } else { - value = o.toString(); - } - } + String value = getValueOf(row, column); if (columnNameKeywordMap.containsKey(colName)) { Color c = JColorChooser.showDialog(getRootPane(), "Choose a color", Color.red); @@ -1695,49 +1635,49 @@ public class LogPanel extends DockablePanel implements EventBatchListener, Profi } } - class Copy extends AbstractAction { - public Copy() { + class CopySelection extends AbstractAction { + public CopySelection() { + super("Copy selection to clipboard"); + } + + public void actionPerformed(ActionEvent e) { + if (currentTable == null) { + return; + } + int start = currentTable.getSelectionModel().getMinSelectionIndex(); + int end = currentTable.getSelectionModel().getMaxSelectionIndex(); + StringBuffer result = new StringBuffer(); + for (int row=start;row<end+1;row++) { + for (int column=0;column<currentTable.getColumnCount();column++) { + result.append(getValueOf(row, column)); + if (column != (currentTable.getColumnCount() - 1)) { + result.append(" - "); + } + } + result.append(System.getProperty("line.separator")); + } + StringSelection selection = new StringSelection(result.toString()); + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + clipboard.setContents(selection, null); + } + } + + class CopyField extends AbstractAction { + public CopyField() { super("Copy value under pointer to clipboard"); } public void actionPerformed(ActionEvent e) { - if (currentPoint != null) { + if (currentPoint != null && currentTable != null) { int column = currentTable.columnAtPoint(currentPoint); int row = currentTable.rowAtPoint(currentPoint); - String colName = currentTable.getColumnName(column).toUpperCase(); - String value = ""; - - if (colName.equalsIgnoreCase(ChainsawConstants.TIMESTAMP_COL_NAME)) { - JComponent comp = - (JComponent) currentTable.getCellRenderer(row, column); - - if (comp instanceof JLabel) { - value = ((JLabel) comp).getText(); - } - } else { - Object o = currentTable.getValueAt(row, column); - //exception - build message + throwable - if (o != null) { - if (o instanceof String[]) { - String[] ti = (String[])o; - if (ti.length > 0 && (!(ti.length == 1 && ti[0].equals("")))) { - LoggingEventWrapper loggingEventWrapper = ((ChainsawCyclicBufferTableModel)(currentTable.getModel())).getRow(row); - value = loggingEventWrapper.getLoggingEvent().getMessage().toString(); - for (int i=0;i<((String[])o).length;i++) { - value = value + "\n" + ((String[]) o)[i]; - } - } - } else { - value = o.toString(); - } - } - } + String value = getValueOf(row, column); StringSelection selection = new StringSelection(value); Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); clipboard.setContents(selection, null); } } - } + } final JMenuItem menuItemToggleDock = new JMenuItem("Undock/dock"); dockingAction = @@ -1769,36 +1709,17 @@ public class LogPanel extends DockablePanel implements EventBatchListener, Profi class Search extends JMenuItem { public Search() { - super("Search for value under pointer"); + super("Find value under pointer"); addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { if (currentPoint != null) { - String operator = "~="; + String operator = "=="; int column = currentTable.columnAtPoint(currentPoint); int row = currentTable.rowAtPoint(currentPoint); String colName = currentTable.getColumnName(column).toUpperCase(); - String value = ""; - - if (colName.equalsIgnoreCase(ChainsawConstants.TIMESTAMP_COL_NAME)) { - try { - value = timestampExpressionFormat.parse(currentTable.getValueAt(row, column).toString()).toString(); - } catch (ParseException e) { - e.printStackTrace(); - } - } else { - Object o = currentTable.getValueAt(row, column); - - if (o != null) { - if (o instanceof String[] && ((String[])o).length > 0) { - value = ((String[]) o)[0]; - } else { - value = o.toString(); - } - } - } - + String value = getValueOf(row, column); if (columnNameKeywordMap.containsKey(colName)) { findCombo.setSelectedItem( columnNameKeywordMap.get(colName).toString() + " " + operator @@ -1823,18 +1744,14 @@ public class LogPanel extends DockablePanel implements EventBatchListener, Profi mainPopup.add(new Search()); searchPopup.add(new Search()); + mainPopup.add(new DefineAddCustomFind()); + searchPopup.add(new DefineAddCustomFind()); mainPopup.add(new ClearSearch()); searchPopup.add(new ClearSearch()); mainPopup.add(new JSeparator()); searchPopup.add(new JSeparator()); - mainPopup.add(new BestFit()); - searchPopup.add(new BestFit()); - - mainPopup.add(new JSeparator()); - searchPopup.add(new JSeparator()); - class DisplayNormalTimes extends JMenuItem { public DisplayNormalTimes() { super("Hide relative times"); @@ -1900,8 +1817,12 @@ public class LogPanel extends DockablePanel implements EventBatchListener, Profi mainPopup.add(new BuildColorRule()); searchPopup.add(new BuildColorRule()); - mainPopup.add(new Copy()); - searchPopup.add(new Copy()); + mainPopup.add(new JSeparator()); + searchPopup.add(new JSeparator()); + mainPopup.add(new CopyField()); + mainPopup.add(new CopySelection()); + searchPopup.add(new CopyField()); + searchPopup.add(new CopySelection()); mainPopup.add(new JSeparator()); searchPopup.add(new JSeparator()); @@ -1913,14 +1834,12 @@ public class LogPanel extends DockablePanel implements EventBatchListener, Profi searchPopup.add(searchToggleToolTips); mainPopup.add(new JSeparator()); - searchPopup.add(new JSeparator()); - - mainPopup.add(menuItemScrollToTop); - mainPopup.add(menuItemScrollBottom); - mainPopup.add(new JSeparator()); mainPopup.add(menuItemToggleDock); + mainPopup.add(new BestFit()); + searchPopup.add(new BestFit()); + mainPopup.add(new JSeparator()); mainPopup.add(new ColorPanel()); @@ -1932,11 +1851,108 @@ public class LogPanel extends DockablePanel implements EventBatchListener, Profi eventsPane.addMouseListener(mainTablePopupListener); table.addMouseListener(mainTablePopupListener); + table.addMouseListener(new MouseListener(){ + public void mouseClicked(MouseEvent mouseEvent) { + checkMultiSelect(mouseEvent); + } + + public void mousePressed(MouseEvent mouseEvent) { + checkMultiSelect(mouseEvent); + } + + public void mouseReleased(MouseEvent mouseEvent) { + checkMultiSelect(mouseEvent); + } + + public void mouseEntered(MouseEvent mouseEvent) { + checkMultiSelect(mouseEvent); + } + + public void mouseExited(MouseEvent mouseEvent) { + checkMultiSelect(mouseEvent); + } + + private void checkMultiSelect(MouseEvent mouseEvent) { + if (mouseEvent.isAltDown()) { + table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); + } else { + table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + } + } + }); + + + searchTable.addMouseListener(new MouseListener(){ + public void mouseClicked(MouseEvent mouseEvent) { + checkMultiSelect(mouseEvent); + } + + public void mousePressed(MouseEvent mouseEvent) { + checkMultiSelect(mouseEvent); + } + + public void mouseReleased(MouseEvent mouseEvent) { + checkMultiSelect(mouseEvent); + } + + public void mouseEntered(MouseEvent mouseEvent) { + checkMultiSelect(mouseEvent); + } + + public void mouseExited(MouseEvent mouseEvent) { + checkMultiSelect(mouseEvent); + } + + private void checkMultiSelect(MouseEvent mouseEvent) { + if (mouseEvent.isAltDown()) { + searchTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); + } else { + searchTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + } + } + }); + + final PopupListener searchTablePopupListener = new PopupListener(searchPopup); searchPane.addMouseListener(searchTablePopupListener); searchTable.addMouseListener(searchTablePopupListener); } + private String getValueOf(int row, int column) { + if (currentTable == null) { + return ""; + } + + Object o = currentTable.getValueAt(row, column); + + if (o instanceof Date) { + return TIMESTAMP_DATE_FORMAT.format((Date)o); + } + + if (o instanceof String) { + return (String)o; + } + + if (o instanceof Level) { + return o.toString(); + } + + if (o instanceof String[]) { + String value = ""; + //exception - build message + throwable + String[] ti = (String[])o; + if (ti.length > 0 && (!(ti.length == 1 && ti[0].equals("")))) { + LoggingEventWrapper loggingEventWrapper = ((ChainsawCyclicBufferTableModel)(currentTable.getModel())).getRow(row); + value = loggingEventWrapper.getLoggingEvent().getMessage().toString(); + for (int i=0;i<((String[])o).length;i++) { + value = value + "\n" + ((String[]) o)[i]; + } + } + return value; + } + return ""; + } + private Action getFindNextAction() { final Action action = new AbstractAction("Find next") { @@ -1988,7 +2004,7 @@ public class LogPanel extends DockablePanel implements EventBatchListener, Profi if (isFiltering) { filterText.getDocument().addDocumentListener(new DelayedTextDocumentListener(filterText)); } - filterText.setToolTipText("Enter an expression, press enter to add to list"); + filterText.setToolTipText("Enter an expression - right click or ctrl-space for menu - press enter to add to list"); filterText.addKeyListener(new ExpressionRuleContext(filterModel, filterText)); if (combo.getEditor().getEditorComponent() instanceof JTextField) { @@ -2604,7 +2620,7 @@ public class LogPanel extends DockablePanel implements EventBatchListener, Profi //reset background color in case we were previously an invalid expression findCombo.setBackground(UIManager.getColor("TextField.background")); findCombo.setToolTipText( - "Enter expression - right click or ctrl-space for menu"); + "Enter an expression - right click or ctrl-space for menu - press enter to add to list"); currentSearchMatchCount = 0; currentFindRuleText = null; statusBar.setSearchMatchCount(currentSearchMatchCount, getIdentifier()); @@ -2621,8 +2637,9 @@ public class LogPanel extends DockablePanel implements EventBatchListener, Profi } currentFindRuleText = ruleText; try { - findCombo.setToolTipText( - "Enter expression - right click or ctrl-space for menu"); + final JTextField findText =(JTextField) findCombo.getEditor().getEditorComponent(); + findText.setToolTipText( + "Enter an expression - right click or ctrl-space for menu - press enter to add to list"); findRule = ExpressionRule.getRule(ruleText); currentSearchMatchCount = tableModel.updateEventsWithFindRule(findRule); searchModel.updateEventsWithFindRule(findRule); @@ -2630,15 +2647,16 @@ public class LogPanel extends DockablePanel implements EventBatchListener, Profi tableRuleMediator.setFindRule(findRule); searchRuleMediator.setFindRule(findRule); //valid expression, reset background color in case we were previously an invalid expression - findCombo.setBackground(UIManager.getColor("TextField.background")); + findText.setBackground(UIManager.getColor("TextField.background")); statusBar.setSearchMatchCount(currentSearchMatchCount, getIdentifier()); if (isSearchResultsVisible()) { showSearchResults(); } } catch (IllegalArgumentException re) { findRule = null; - findCombo.setToolTipText(re.getMessage()); - findCombo.setBackground(ChainsawConstants.INVALID_EXPRESSION_BACKGROUND); + final JTextField findText =(JTextField) findCombo.getEditor().getEditorComponent(); + findText.setToolTipText(re.getMessage()); + findText.setBackground(ChainsawConstants.INVALID_EXPRESSION_BACKGROUND); colorizer.setFindRule(null); tableRuleMediator.setFindRule(null); searchRuleMediator.setFindRule(null); @@ -3012,6 +3030,7 @@ public class LogPanel extends DockablePanel implements EventBatchListener, Profi if (findRule != null) { EventQueue.invokeLater(new Runnable() { public void run() { + final JTextField findText =(JTextField) findCombo.getEditor().getEditorComponent(); try { int filteredEventsSize = getFilteredEvents().size(); int startRow = table.getSelectedRow() + 1; @@ -3023,10 +3042,12 @@ public class LogPanel extends DockablePanel implements EventBatchListener, Profi if (nextRow > -1) { table.scrollToRow(nextRow); - findCombo.setToolTipText("Enter an expression"); + findText.setToolTipText("Enter an expression - right click or ctrl-space for menu - press enter to add to list"); } + findText.setBackground(UIManager.getColor("TextField.background")); } catch (IllegalArgumentException iae) { - findCombo.setToolTipText(iae.getMessage()); + findText.setToolTipText(iae.getMessage()); + findText.setBackground(ChainsawConstants.INVALID_EXPRESSION_BACKGROUND); colorizer.setFindRule(null); tableRuleMediator.setFindRule(null); searchRuleMediator.setFindRule(null); @@ -3048,6 +3069,7 @@ public class LogPanel extends DockablePanel implements EventBatchListener, Profi if (findRule != null) { EventQueue.invokeLater(new Runnable() { public void run() { + final JTextField findText =(JTextField) findCombo.getEditor().getEditorComponent(); try { int startRow = table.getSelectedRow() - 1; int filteredEventsSize = getFilteredEvents().size(); @@ -3058,10 +3080,12 @@ public class LogPanel extends DockablePanel implements EventBatchListener, Profi if (previousRow > -1) { table.scrollToRow(previousRow); - findCombo.setToolTipText("Enter an expression"); + findCombo.setToolTipText("Enter an expression - right click or ctrl-space for menu - press enter to add to list"); } + findText.setBackground(UIManager.getColor("TextField.background")); } catch (IllegalArgumentException iae) { - findCombo.setToolTipText(iae.getMessage()); + findText.setToolTipText(iae.getMessage()); + findText.setBackground(ChainsawConstants.INVALID_EXPRESSION_BACKGROUND); } } }); @@ -3296,6 +3320,19 @@ public class LogPanel extends DockablePanel implements EventBatchListener, Profi } } + public void setFindText(String findText) { + findCombo.setSelectedItem(findText); + findNext(); + } + + public String getFindText() { + Object selectedItem = findCombo.getSelectedItem(); + if (selectedItem == null) { + return ""; + } + return selectedItem.toString(); + } + /** * This class receives notification when the Refine focus or find field is * updated, where a background thread periodically wakes up and checks if @@ -3419,28 +3456,6 @@ public class LogPanel extends DockablePanel implements EventBatchListener, Profi } } } - - private void setFind() { - if (textField.getText().trim().equals("")) { - //reset background color in case we were previously an invalid expression - textField.setBackground(UIManager.getColor("TextField.background")); - tableRuleMediator.setFindRule(null); - searchRuleMediator.setFindRule(null); - textField.setToolTipText(defaultToolTip); - } else { - try { - tableRuleMediator.setFindRule(ExpressionRule.getRule(textField.getText())); - searchRuleMediator.setFindRule(ExpressionRule.getRule(textField.getText())); - textField.setToolTipText(defaultToolTip); - //valid expression, reset background color in case we were previously an invalid expression - textField.setBackground(UIManager.getColor("TextField.background")); - } catch (IllegalArgumentException iae) { - //invalid expression, change background of the field - textField.setToolTipText(iae.getMessage()); - textField.setBackground(ChainsawConstants.INVALID_EXPRESSION_BACKGROUND); - } - } - } } private final class TableMarkerListener extends MouseAdapter { http://git-wip-us.apache.org/repos/asf/logging-chainsaw/blob/9f01847a/src/main/java/org/apache/log4j/chainsaw/LoggerNameTreePanel.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/log4j/chainsaw/LoggerNameTreePanel.java b/src/main/java/org/apache/log4j/chainsaw/LoggerNameTreePanel.java index f5ac429..ff01eed 100644 --- a/src/main/java/org/apache/log4j/chainsaw/LoggerNameTreePanel.java +++ b/src/main/java/org/apache/log4j/chainsaw/LoggerNameTreePanel.java @@ -24,7 +24,6 @@ import java.awt.Component; import java.awt.Cursor; import java.awt.Dimension; import java.awt.EventQueue; -import java.awt.FlowLayout; import java.awt.Font; import java.awt.Point; import java.awt.Toolkit; @@ -120,11 +119,12 @@ final class LoggerNameTreePanel extends JPanel implements LoggerNameListener private final Action editLoggerAction; private final JButton editLoggerButton = new SmallButton(); private final Action expandAction; - private final Action findNextAction; + private final Action findAction; private final Action clearFindNextAction; private final Action defineColorRuleForLoggerAction; private final Action setRefineFocusAction; private final Action updateRefineFocusAction; + private final Action updateFindAction; private final JButton expandButton = new SmallButton(); private final Action focusOnAction; private final Action clearRefineFocusAction; @@ -270,12 +270,13 @@ final class LoggerNameTreePanel extends JPanel implements LoggerNameListener toolbar.setLayout(new BoxLayout(toolbar, BoxLayout.X_AXIS)); expandAction = createExpandAction(); - findNextAction = createFindNextAction(); + findAction = createFindNextAction(); clearFindNextAction = createClearFindNextAction(); defineColorRuleForLoggerAction = createDefineColorRuleForLoggerAction(); clearRefineFocusAction = createClearRefineFocusAction(); setRefineFocusAction = createSetRefineFocusAction(); updateRefineFocusAction = createUpdateRefineFocusAction(); + updateFindAction = createUpdateFindAction(); editLoggerAction = createEditLoggerAction(); closeAction = createCloseAction(); collapseAction = createCollapseAction(); @@ -873,6 +874,38 @@ final class LoggerNameTreePanel extends JPanel implements LoggerNameListener return action; } + private Action createUpdateFindAction() + { + Action action = new AbstractAction() + { + public void actionPerformed(ActionEvent e) + { + updateFindUsingCurrentlySelectedNode(); + } + }; + + action.putValue(Action.NAME, "Update 'find' to include selected logger"); + action.putValue( + Action.SHORT_DESCRIPTION, + "Add selected node to 'find' field"); + action.setEnabled(false); + + return action; + } + + private void updateFindUsingCurrentlySelectedNode() + { + String selectedLogger = getCurrentlySelectedLoggerName(); + TreePath[] paths = logTree.getSelectionPaths(); + + if (paths == null) + { + return; + } + String currentFindText = logPanel.getFindText(); + logPanel.setFindText(currentFindText + " || logger ~= " + selectedLogger); + } + private void updateRefineFocusUsingCurrentlySelectedNode() { String selectedLogger = getCurrentlySelectedLoggerName(); @@ -1116,12 +1149,12 @@ final class LoggerNameTreePanel extends JPanel implements LoggerNameListener { return; } - visibilityRuleDelegate.firePropertyChange("searchExpression", null, "logger like '^" + selectedLogger + ".*'"); + logPanel.setFindText("logger like '^" + selectedLogger + ".*'"); } private void clearFindNext() { - visibilityRuleDelegate.firePropertyChange("searchExpression", null, ""); + logPanel.setFindText(""); } private void clearRefineFocus() @@ -1238,18 +1271,20 @@ final class LoggerNameTreePanel extends JPanel implements LoggerNameListener { focusOnAction.putValue(Action.NAME, "Focus On..."); hideAction.putValue(Action.NAME, "Ignore..."); - findNextAction.putValue(Action.NAME, "Find..."); + findAction.putValue(Action.NAME, "Find..."); setRefineFocusAction.putValue(Action.NAME, "Set refine focus field"); updateRefineFocusAction.putValue(Action.NAME, "Add to refine focus field"); + updateFindAction.putValue(Action.NAME, "Add to find field"); defineColorRuleForLoggerAction.putValue(Action.NAME, "Define color rule"); } else { focusOnAction.putValue(Action.NAME, "Focus On '" + logger + "'"); hideAction.putValue(Action.NAME, "Ignore '" + logger + "'"); - findNextAction.putValue(Action.NAME, "Find '" + logger + "'"); + findAction.putValue(Action.NAME, "Find '" + logger + "'"); setRefineFocusAction.putValue(Action.NAME, "Set refine focus field to '" + logger + "'"); updateRefineFocusAction.putValue(Action.NAME, "Add '" + logger + "' to 'refine focus' field"); + updateFindAction.putValue(Action.NAME, "Add '" + logger + "' to 'find' field"); defineColorRuleForLoggerAction.putValue(Action.NAME, "Define color rule for '" + logger + "'"); } @@ -1298,11 +1333,12 @@ final class LoggerNameTreePanel extends JPanel implements LoggerNameListener } expandAction.setEnabled(path != null); - findNextAction.setEnabled(path != null); + findAction.setEnabled(path != null); clearFindNextAction.setEnabled(true); defineColorRuleForLoggerAction.setEnabled(path != null); setRefineFocusAction.setEnabled(path != null); updateRefineFocusAction.setEnabled(path != null); + updateFindAction.setEnabled(path != null); clearRefineFocusAction.setEnabled(true); if (currentlySelectedLoggerName != null) @@ -1632,7 +1668,8 @@ final class LoggerNameTreePanel extends JPanel implements LoggerNameListener add(updateRefineFocusAction); add(clearRefineFocusAction); addSeparator(); - add(findNextAction); + add(findAction); + add(updateFindAction); add(clearFindNextAction); addSeparator(); http://git-wip-us.apache.org/repos/asf/logging-chainsaw/blob/9f01847a/src/main/java/org/apache/log4j/chainsaw/TableColorizingRenderer.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/log4j/chainsaw/TableColorizingRenderer.java b/src/main/java/org/apache/log4j/chainsaw/TableColorizingRenderer.java index 209204d..983db9a 100644 --- a/src/main/java/org/apache/log4j/chainsaw/TableColorizingRenderer.java +++ b/src/main/java/org/apache/log4j/chainsaw/TableColorizingRenderer.java @@ -179,7 +179,7 @@ public class TableColorizingRenderer extends DefaultTableCellRenderer { int row, int col) { EventContainer container = (EventContainer) table.getModel(); LoggingEventWrapper loggingEventWrapper = container.getRow(row); - value = formatField(value, row, loggingEventWrapper); + value = formatField(value, loggingEventWrapper); TableColumn tableColumn = table.getColumnModel().getColumn(col); int width = tableColumn.getWidth(); JLabel label = (JLabel)super.getTableCellRendererComponent(table, value, @@ -569,10 +569,9 @@ public class TableColorizingRenderer extends DefaultTableCellRenderer { * * @param field object * - * @param renderingRow * @return formatted object */ - private Object formatField(Object field, int renderingRow, LoggingEventWrapper loggingEventWrapper) { + private Object formatField(Object field, LoggingEventWrapper loggingEventWrapper) { if (!(field instanceof Date)) { return (field == null ? "" : field); } http://git-wip-us.apache.org/repos/asf/logging-chainsaw/blob/9f01847a/src/main/java/org/apache/log4j/chainsaw/color/ColorPanel.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/log4j/chainsaw/color/ColorPanel.java b/src/main/java/org/apache/log4j/chainsaw/color/ColorPanel.java index 6234680..dcc4621 100644 --- a/src/main/java/org/apache/log4j/chainsaw/color/ColorPanel.java +++ b/src/main/java/org/apache/log4j/chainsaw/color/ColorPanel.java @@ -265,16 +265,22 @@ public class ColorPanel extends JPanel public void actionPerformed(ActionEvent e) { tableModel.getDataVector().clear(); - RuleColorizer sourceColorizer = (RuleColorizer) allLogPanelColorizers.get(loadPanelColorizersComboBox.getSelectedItem().toString()); - colorizer.setRules(sourceColorizer.getRules()); - updateColors(); + Object selectedItem = loadPanelColorizersComboBox.getSelectedItem(); + if (selectedItem != null) { + RuleColorizer sourceColorizer = (RuleColorizer) allLogPanelColorizers.get(selectedItem.toString()); + colorizer.setRules(sourceColorizer.getRules()); + updateColors(); + } } }; loadPanelColorizersComboBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - String selectedColorizerName = loadPanelColorizersComboBox.getSelectedItem().toString(); - copyRulesAction.setEnabled(!(noTab.equals(selectedColorizerName))); + Object selectedItem = loadPanelColorizersComboBox.getSelectedItem(); + if (selectedItem != null) { + String selectedColorizerName = selectedItem.toString(); + copyRulesAction.setEnabled(!(noTab.equals(selectedColorizerName))); + } } }); http://git-wip-us.apache.org/repos/asf/logging-chainsaw/blob/9f01847a/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html ---------------------------------------------------------------------- diff --git a/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html b/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html index 59a0fb5..c9799bc 100644 --- a/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html +++ b/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html @@ -13,6 +13,7 @@ <h2>6 Nov 2010</h2> <ul> <li>Log file receiver configurations can now be loaded from both log4j.xml and log4j.properties configuration fileappender entries</li> +<li>Added multi-select capability to event table and 'copy selection' context menu item (multi-select by holding down alt key while selecting rows)</li> </ul> <h2>5 Nov 2010</h2> <ul>
