Author: sdeboy Date: Mon Oct 18 07:46:19 2010 New Revision: 1023677 URL: http://svn.apache.org/viewvc?rev=1023677&view=rev Log: Performance improvement & UI update - since color rules aren't different between search & main tables, just update the associated search event's color directly without re-running a rule evaluation - moved search field next to refine focus field Modified: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ChainsawToolBarAndMenus.java logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanel.java logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LoggingEventWrapper.java Modified: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ChainsawToolBarAndMenus.java URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ChainsawToolBarAndMenus.java?rev=1023677&r1=1023676&r2=1023677&view=diff ============================================================================== --- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ChainsawToolBarAndMenus.java (original) +++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ChainsawToolBarAndMenus.java Mon Oct 18 07:46:19 2010 @@ -18,9 +18,7 @@ package org.apache.log4j.chainsaw; import java.awt.BorderLayout; -import java.awt.Component; import java.awt.Dimension; -import java.awt.Font; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -36,7 +34,6 @@ import java.util.List; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.Box; -import javax.swing.BoxLayout; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBoxMenuItem; @@ -49,7 +46,6 @@ import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JRadioButtonMenuItem; -import javax.swing.JTextField; import javax.swing.JToolBar; import javax.swing.KeyStroke; import javax.swing.SwingConstants; @@ -72,12 +68,9 @@ import org.apache.log4j.chainsaw.receive */ class ChainsawToolBarAndMenus implements ChangeListener { private final SmallToggleButton showReceiversButton; - private final JTextField findField; private final Action changeModelAction; private final Action clearAction; private final Action toggleWelcomeVisibleAction; - private final Action findNextAction; - private final Action findPreviousAction; private final Action findPreviousColorizedEventAction; private final Action findNextColorizedEventAction; private final Action findNextMarkerAction; @@ -122,7 +115,6 @@ class ChainsawToolBarAndMenus implements private final SmallToggleButton toggleCyclicButton = new SmallToggleButton(); private final Action[] logPanelSpecificActions; private final JMenu activeTabMenu = new JMenu("Current tab"); - private final JPanel findPanel; ChainsawToolBarAndMenus(final LogUI logui) { this.logui = logui; @@ -131,9 +123,6 @@ class ChainsawToolBarAndMenus implements fileMenu = new FileMenu(logui); toggleWelcomeVisibleAction = toggleWelcomeVisibleAction(); changeModelAction = createChangeModelAction(); - findField = new JTextField(); - findNextAction = getFindNextAction(); - findPreviousAction = getFindPreviousAction(); findNextMarkerAction = createFindNextMarkerAction(); findPreviousColorizedEventAction = getFindPreviousColorizedEventAction(); findNextColorizedEventAction = getFindNextColorizedEventAction(); @@ -153,28 +142,13 @@ class ChainsawToolBarAndMenus implements showReceiversAction = createShowReceiversAction(); showReceiversButton = new SmallToggleButton(showReceiversAction); - findPanel = new JPanel(); - findPanel.setLayout(new BoxLayout(findPanel, BoxLayout.X_AXIS)); - - Dimension findSize = new Dimension(260, 22); - Dimension findPanelSize = new Dimension(310, 30); - findPanel.setPreferredSize(findPanelSize); - findPanel.setMaximumSize(findPanelSize); - findPanel.setMinimumSize(findPanelSize); - - findField.setPreferredSize(findSize); - findField.setMaximumSize(findSize); - findField.setMinimumSize(findSize); - findPanel.setAlignmentY(Component.CENTER_ALIGNMENT); - findField.setAlignmentY(Component.CENTER_ALIGNMENT); - toggleDetailPaneAction = createToggleDetailPaneAction(); createMenuBar(); createToolbar(); logPanelSpecificActions = new Action[] { - pauseAction, findNextAction, findPreviousAction, findNextColorizedEventAction, findPreviousColorizedEventAction, + pauseAction, findNextColorizedEventAction, findPreviousColorizedEventAction, findNextMarkerAction, findPreviousMarkerAction, toggleMarkerAction, clearAllMarkersAction, scrollToTopAction, clearAction, fileMenu.getFileSaveAction(), toggleDetailPaneAction, @@ -817,39 +791,6 @@ class ChainsawToolBarAndMenus implements clearButton.setText(""); toolbar.addSeparator(); - JButton findNextButton = new SmallButton(findNextAction); - findNextButton.setText(""); - findNextButton.getActionMap().put( - findNextAction.getValue(Action.NAME), findNextAction); - findNextButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put( - (KeyStroke) findNextAction.getValue(Action.ACCELERATOR_KEY), - findNextAction.getValue(Action.NAME)); - - JButton findPreviousButton = new SmallButton(findPreviousAction); - findPreviousButton.setText(""); - findPreviousButton.getActionMap().put( - findPreviousAction.getValue(Action.NAME), findPreviousAction); - findPreviousButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put( - (KeyStroke) findPreviousAction.getValue(Action.ACCELERATOR_KEY), - findPreviousAction.getValue(Action.NAME)); - - JLabel searchLabel = new JLabel("Search:"); - searchLabel.setDisplayedMnemonic('j'); - searchLabel.setFont(searchLabel.getFont().deriveFont(Font.BOLD)); - findPanel.add(searchLabel); - findPanel.add(Box.createHorizontalStrut(3)); - findPanel.add(findField); - findPanel.add(Box.createRigidArea(new Dimension(5, 0))); - searchLabel.setLabelFor(findField); - - - toolbar.add(findPanel); - toolbar.addSeparator(new Dimension(7, 5)); - toolbar.add(findNextButton); - toolbar.add(findPreviousButton); - - toolbar.addSeparator(); - showReceiversButton.setText(null); toolbar.add(showReceiversButton); @@ -907,17 +848,6 @@ class ChainsawToolBarAndMenus implements if (logPanel == null) { activateLogPanelActions = false; - findField.setEnabled(false); - findPanel.removeAll(); - JLabel searchLabel = new JLabel("Search:"); - searchLabel.setDisplayedMnemonic('j'); - searchLabel.setFont(searchLabel.getFont().deriveFont(Font.BOLD)); - findPanel.add(searchLabel); - findPanel.add(Box.createHorizontalStrut(3)); - - findPanel.add(findField); - findPanel.add(Box.createRigidArea(new Dimension(5, 0))); - searchLabel.setLabelFor(findField); activeTabMenu.setEnabled(false); toggleWelcomeVisibleAction.setEnabled(true); detailPaneButton.setSelected(false); @@ -925,17 +855,6 @@ class ChainsawToolBarAndMenus implements } else { activeTabMenu.setEnabled(true); fileMenu.getFileSaveAction().setEnabled(true); - findPanel.removeAll(); - JLabel searchLabel = new JLabel("Search:"); - searchLabel.setDisplayedMnemonic('j'); - - searchLabel.setFont(searchLabel.getFont().deriveFont(Font.BOLD)); - findPanel.add(searchLabel); - findPanel.add(Box.createHorizontalStrut(3)); - findPanel.add(logPanel.getFindTextField()); - findPanel.add(Box.createRigidArea(new Dimension(5, 0))); - searchLabel.setLabelFor(logPanel.getFindTextField()); - pauseButton.getModel().setSelected(logPanel.isPaused()); toggleCyclicButton.setSelected(logPanel.isCyclic()); logui.getStatusBar().setPaused(logPanel.isPaused(), logPanel.getIdentifier()); @@ -945,10 +864,6 @@ class ChainsawToolBarAndMenus implements toggleScrollToBottomMenuItem.setSelected(logPanel.isScrollToBottom()); } - findPanel.invalidate(); - findPanel.revalidate(); - findPanel.repaint(); - for (int i = 0; i < logPanelSpecificActions.length; i++) { logPanelSpecificActions[i].setEnabled(activateLogPanelActions); } @@ -966,52 +881,6 @@ class ChainsawToolBarAndMenus implements } } - private Action getFindNextAction() { - final Action action = - new AbstractAction("Find next") { - public void actionPerformed(ActionEvent e) { - LogPanel p = logui.getCurrentLogPanel(); - - if (p != null) { - p.findNext(); - } - } - }; - - // action.putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_F)); - action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("F3")); - action.putValue( - Action.SHORT_DESCRIPTION, - "Find the next occurrence of the rule from the current row"); - action.putValue(Action.SMALL_ICON, new ImageIcon(ChainsawIcons.DOWN)); - - return action; - } - - private Action getFindPreviousAction() { - final Action action = - new AbstractAction("Find previous") { - public void actionPerformed(ActionEvent e) { - LogPanel p = logui.getCurrentLogPanel(); - - if (p != null) { - p.findPrevious(); - } - } - }; - - // action.putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_F)); - action.putValue( - Action.ACCELERATOR_KEY, - KeyStroke.getKeyStroke(KeyEvent.VK_F3, InputEvent.SHIFT_MASK)); - action.putValue( - Action.SHORT_DESCRIPTION, - "Find the previous occurrence of the rule from the current row"); - action.putValue(Action.SMALL_ICON, new ImageIcon(ChainsawIcons.UP)); - - return action; - } - private Action getFindNextColorizedEventAction() { final Action action = new AbstractAction("Find next colorized event") { Modified: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanel.java URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanel.java?rev=1023677&r1=1023676&r2=1023677&view=diff ============================================================================== --- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanel.java (original) +++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanel.java Mon Oct 18 07:46:19 2010 @@ -27,6 +27,8 @@ import java.awt.FlowLayout; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; import java.awt.Point; import java.awt.Toolkit; import java.awt.Window; @@ -61,8 +63,6 @@ import java.text.NumberFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; import java.util.Enumeration; import java.util.EventObject; import java.util.HashMap; @@ -243,8 +243,6 @@ public class LogPanel extends DockablePa private Rule findRule; private String currentFindRuleText; private Rule findMarkerRule; - private final JPanel findPanel; - private JTextField findField; private final int dividerSize; static final String TABLE_COLUMN_ORDER = "table.columns.order"; static final String TABLE_COLUMN_WIDTHS = "table.columns.widths"; @@ -254,6 +252,7 @@ public class LogPanel extends DockablePa private final DateFormat timestampExpressionFormat = new SimpleDateFormat(Constants.TIMESTAMP_RULE_FORMAT); private final Logger logger = LogManager.getLogger(LogPanel.class); private AutoFilterComboBox filterCombo; + private AutoFilterComboBox findCombo; private JScrollPane eventsPane; private int currentSearchMatchCount; private ApplicationPreferenceModel applicationPreferenceModel; @@ -287,12 +286,16 @@ public class LogPanel extends DockablePa logger.debug("creating logpanel for " + identifier); setLayout(new BorderLayout()); - findPanel = new JPanel(); - findPanel.setLayout(new BoxLayout(findPanel, BoxLayout.X_AXIS)); - Dimension findPanelSize = new Dimension(310, 30); - findPanel.setPreferredSize(findPanelSize); - findPanel.setMaximumSize(findPanelSize); - findPanel.setMinimumSize(findPanelSize); + + String prototypeValue = "1231231231231231231231"; + + filterCombo = new AutoFilterComboBox(); + filterCombo.setPrototypeDisplayValue(prototypeValue); + buildCombo(filterCombo, true); + + findCombo = new AutoFilterComboBox(); + findCombo.setPrototypeDisplayValue(prototypeValue); + buildCombo(findCombo, false); final Map columnNameKeywordMap = new HashMap(); columnNameKeywordMap.put(ChainsawConstants.CLASS_COL_NAME, LoggingEventFieldResolver.CLASS_FIELD); @@ -792,7 +795,7 @@ public class LogPanel extends DockablePa public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equals("searchExpression")) { - findField.setText(evt.getNewValue().toString()); + findCombo.setSelectedItem(evt.getNewValue().toString()); findNext(); } } @@ -846,11 +849,13 @@ public class LogPanel extends DockablePa LoggingEventWrapper loggingEventWrapper = (LoggingEventWrapper)iter.next(); loggingEventWrapper.updateColorRuleColors(colorizer.getBackgroundColor(loggingEventWrapper.getLoggingEvent()), colorizer.getForegroundColor(loggingEventWrapper.getLoggingEvent())); } - - for (Iterator iter = searchModel.getAllEvents().iterator();iter.hasNext();) { - LoggingEventWrapper loggingEventWrapper = (LoggingEventWrapper)iter.next(); - loggingEventWrapper.updateColorRuleColors(colorizer.getBackgroundColor(loggingEventWrapper.getLoggingEvent()), colorizer.getForegroundColor(loggingEventWrapper.getLoggingEvent())); - } +// no need to update searchmodel events since tablemodel and searchmodel share all events, and color rules aren't different between the two +// if that changes, un-do the color syncing in loggingeventwrapper & re-enable this code +// +// for (Iterator iter = searchModel.getAllEvents().iterator();iter.hasNext();) { +// LoggingEventWrapper loggingEventWrapper = (LoggingEventWrapper)iter.next(); +// loggingEventWrapper.updateColorRuleColors(colorizer.getBackgroundColor(loggingEventWrapper.getLoggingEvent()), colorizer.getForegroundColor(loggingEventWrapper.getLoggingEvent())); +// } colorizedEventAndSearchMatchThumbnail.configureColors(); lowerPanel.invalidate(); lowerPanel.revalidate(); @@ -1092,90 +1097,90 @@ public class LogPanel extends DockablePa /* * Upper panel definition */ - JPanel upperPanel = new JPanel(new BorderLayout()); + JPanel upperPanel = new JPanel(); + upperPanel.setLayout(new BoxLayout(upperPanel, BoxLayout.X_AXIS)); upperPanel.setBorder(BorderFactory.createEmptyBorder(2, 5, 2, 0)); final JLabel filterLabel = new JLabel("Refine focus on: "); filterLabel.setFont(filterLabel.getFont().deriveFont(Font.BOLD)); filterLabel.setDisplayedMnemonic('k'); + filterLabel.setLabelFor(filterCombo); - JPanel upperLeftPanel = new JPanel(); - upperLeftPanel.setLayout(new BoxLayout(upperLeftPanel, BoxLayout.X_AXIS)); - upperLeftPanel.setAlignmentY(Component.CENTER_ALIGNMENT); - upperLeftPanel.setAlignmentY(Component.CENTER_ALIGNMENT); - - upperLeftPanel.add(filterLabel); + upperPanel.add(filterLabel); - //add (hopefully useful) default filters - Vector filterExpressionVector = new Vector(); - filterExpressionVector.add("LEVEL == TRACE"); - filterExpressionVector.add("LEVEL >= DEBUG"); - filterExpressionVector.add("LEVEL >= INFO"); - filterExpressionVector.add("LEVEL >= WARN"); - filterExpressionVector.add("LEVEL >= ERROR"); - filterExpressionVector.add("LEVEL == FATAL"); - - filterCombo = new AutoFilterComboBox(filterExpressionVector); - final JTextField filterText =(JTextField) filterCombo.getEditor().getEditorComponent(); - filterText.getDocument().addDocumentListener(new DelayedFilterTextDocumentListener(filterText)); - filterText.setToolTipText("Enter an expression, press enter to add to list"); - filterText.addKeyListener(new ExpressionRuleContext(filterModel, filterText)); - - if (filterCombo.getEditor().getEditorComponent() instanceof JTextField) { - filterCombo.addActionListener( - new AbstractAction() { - public void actionPerformed(ActionEvent e) { - if (e.getActionCommand().equals("comboBoxEdited")) { - try { - //verify the expression is valid - Object item = filterCombo.getSelectedItem(); - if (item != null && !item.toString().trim().equals("")) { - ExpressionRule.getRule(item.toString()); - //add entry as first row of the combo box - filterCombo.insertItemAt(item, 0); - } - //valid expression, reset background color in case we were previously an invalid expression - filterText.setBackground(UIManager.getColor("TextField.background")); - } catch (IllegalArgumentException iae) { - //don't add expressions that aren't valid - //invalid expression, change background of the field - filterText.setToolTipText(iae.getMessage()); - filterText.setBackground(ChainsawConstants.INVALID_EXPRESSION_BACKGROUND); - return; - } - } - } - }); - } - upperPanel.add(filterCombo, BorderLayout.CENTER); - filterLabel.setLabelFor(filterCombo); - - upperPanel.add(upperLeftPanel, BorderLayout.WEST); - - JPanel upperRightPanel = - new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0)); + upperPanel.add(filterCombo); //Adding a button to clear filter expressions which are currently remembered by Chainsaw... - final JButton clearButton = new JButton(" Clear expression "); - clearButton.setToolTipText("Click here to remove the selected expression from the list"); - clearButton.addActionListener( + final JButton removeFilterButton = new JButton(" Remove "); + final JTextField filterText =(JTextField) filterCombo.getEditor().getEditorComponent(); + removeFilterButton.setToolTipText("Click here to remove the selected expression from the list"); + removeFilterButton.addActionListener( new AbstractAction() { public void actionPerformed(ActionEvent e){ Object selectedItem = filterCombo.getSelectedItem(); - if (e.getSource() == clearButton && selectedItem != null && !selectedItem.toString().trim().equals("")){ - //don't just remove the entry from the store, clear the refine focus field - filterText.setText(null); + if (e.getSource() == removeFilterButton && selectedItem != null && !selectedItem.toString().trim().equals("")){ + //don't just remove the entry from the store, clear the field int index = filterCombo.getSelectedIndex(); + filterText.setText(null); filterCombo.setSelectedIndex(-1); filterCombo.removeItemAt(index); } } } ); + upperPanel.add(removeFilterButton); + + final JLabel findLabel = new JLabel("Search: "); + findLabel.setFont(filterLabel.getFont().deriveFont(Font.BOLD)); + findLabel.setDisplayedMnemonic('j'); + findLabel.setLabelFor(findCombo); + + upperPanel.add(findLabel); + + upperPanel.add(findCombo); + + Action findNextAction = getFindNextAction(); + Action findPreviousAction = getFindPreviousAction(); + //add up & down search + JButton findNextButton = new SmallButton(findNextAction); + findNextButton.setText(""); + findNextButton.getActionMap().put( + findNextAction.getValue(Action.NAME), findNextAction); + findNextButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put( + (KeyStroke) findNextAction.getValue(Action.ACCELERATOR_KEY), + findNextAction.getValue(Action.NAME)); + + JButton findPreviousButton = new SmallButton(findPreviousAction); + findPreviousButton.setText(""); + findPreviousButton.getActionMap().put( + findPreviousAction.getValue(Action.NAME), findPreviousAction); + findPreviousButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put( + (KeyStroke) findPreviousAction.getValue(Action.ACCELERATOR_KEY), + findPreviousAction.getValue(Action.NAME)); - upperRightPanel.add(clearButton); + upperPanel.add(findNextButton); - upperPanel.add(upperRightPanel, BorderLayout.EAST); + upperPanel.add(findPreviousButton); + + //Adding a button to clear filter expressions which are currently remembered by Chainsaw... + final JButton removeFindButton = new JButton(" Remove "); + final JTextField findText =(JTextField) findCombo.getEditor().getEditorComponent(); + removeFindButton.setToolTipText("Click here to remove the selected expression from the list"); + removeFindButton.addActionListener( + new AbstractAction() { + public void actionPerformed(ActionEvent e){ + Object selectedItem = findCombo.getSelectedItem(); + if (e.getSource() == removeFindButton && selectedItem != null && !selectedItem.toString().trim().equals("")){ + //don't just remove the entry from the store, clear the field + int index = findCombo.getSelectedIndex(); + findText.setText(null); + findCombo.setSelectedIndex(-1); + findCombo.removeItemAt(index); + } + } + } + ); + upperPanel.add(removeFindButton); /* * Detail pane definition @@ -1312,7 +1317,7 @@ public class LogPanel extends DockablePa //no-op empty searches return; } - findField.setText("msg ~= '" + selectedText + "'"); + findCombo.setSelectedItem("msg ~= '" + selectedText + "'"); findNext(); } }; @@ -1732,7 +1737,7 @@ public class LogPanel extends DockablePa } if (columnNameKeywordMap.containsKey(colName)) { - findField.setText( + findCombo.setSelectedItem( columnNameKeywordMap.get(colName).toString() + " " + operator + " '" + value + "'"); findNext(); @@ -1748,7 +1753,7 @@ public class LogPanel extends DockablePa super("Clear search field"); } public void actionPerformed(ActionEvent e) { - findField.setText(null); + findCombo.setSelectedItem(null); updateFindRule(null); } } @@ -1869,6 +1874,87 @@ public class LogPanel extends DockablePa detailPane.addMouseListener(searchTablePopupListener); } + private Action getFindNextAction() { + final Action action = + new AbstractAction("Find next") { + public void actionPerformed(ActionEvent e) { + findNext(); + } + }; + + // action.putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_F)); + action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("F3")); + action.putValue( + Action.SHORT_DESCRIPTION, + "Find the next occurrence of the rule from the current row"); + action.putValue(Action.SMALL_ICON, new ImageIcon(ChainsawIcons.DOWN)); + + return action; + } + + private Action getFindPreviousAction() { + final Action action = + new AbstractAction("Find previous") { + public void actionPerformed(ActionEvent e) { + findPrevious(); + } + }; + + // action.putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_F)); + action.putValue( + Action.ACCELERATOR_KEY, + KeyStroke.getKeyStroke(KeyEvent.VK_F3, InputEvent.SHIFT_MASK)); + action.putValue( + Action.SHORT_DESCRIPTION, + "Find the previous occurrence of the rule from the current row"); + action.putValue(Action.SMALL_ICON, new ImageIcon(ChainsawIcons.UP)); + + return action; + } + + private void buildCombo(final JComboBox combo, boolean isFiltering) { + //add (hopefully useful) default filters + combo.addItem("LEVEL == TRACE"); + combo.addItem("LEVEL >= DEBUG"); + combo.addItem("LEVEL >= INFO"); + combo.addItem("LEVEL >= WARN"); + combo.addItem("LEVEL >= ERROR"); + combo.addItem("LEVEL == FATAL"); + + final JTextField filterText =(JTextField) combo.getEditor().getEditorComponent(); + if (isFiltering) { + filterText.getDocument().addDocumentListener(new DelayedTextDocumentListener(filterText)); + } + filterText.setToolTipText("Enter an expression, press enter to add to list"); + filterText.addKeyListener(new ExpressionRuleContext(filterModel, filterText)); + + if (combo.getEditor().getEditorComponent() instanceof JTextField) { + combo.addActionListener( + new AbstractAction() { + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand().equals("comboBoxEdited")) { + try { + //verify the expression is valid + Object item = combo.getSelectedItem(); + if (item != null && !item.toString().trim().equals("")) { + ExpressionRule.getRule(item.toString()); + //add entry as first row of the combo box + combo.insertItemAt(item, 0); + } + //valid expression, reset background color in case we were previously an invalid expression + filterText.setBackground(UIManager.getColor("TextField.background")); + } catch (IllegalArgumentException iae) { + //don't add expressions that aren't valid + //invalid expression, change background of the field + filterText.setToolTipText(iae.getMessage()); + filterText.setBackground(ChainsawConstants.INVALID_EXPRESSION_BACKGROUND); + } + } + } + }); + } + } + /** * Accessor * @@ -2080,6 +2166,7 @@ public class LogPanel extends DockablePa Object item = savedVector.get(i); //insert each row at index zero (so last row in vector will be row zero) filterCombo.insertItemAt(item, 0); + findCombo.insertItemAt(item, 0); } if (versionNumber > 1) { //update prefModel columns to include defaults @@ -2212,7 +2299,11 @@ public class LogPanel extends DockablePa //this is a version number written to the file to identify that there is a Vector serialized after this s.writeInt(LOG_PANEL_SERIALIZATION_VERSION_NUMBER); //don't write filterexpressionvector, write the combobox's model's backing vector - s.writeObject(filterCombo.getModelData()); + Vector combinedVector = new Vector(); + combinedVector.addAll(filterCombo.getModelData()); + combinedVector.addAll(findCombo.getModelData()); + //duplicates will be removed when loaded.. + s.writeObject(combinedVector); } catch (Exception ex) { ex.printStackTrace(); // TODO need to log this.. @@ -2342,18 +2433,6 @@ public class LogPanel extends DockablePa final int row = table.getSelectedRow(); setDocked(false); externalPanel.removeAll(); - findPanel.removeAll(); - - JLabel searchLabel = new JLabel("Search:"); - searchLabel.setDisplayedMnemonic('j'); - - searchLabel.setFont(searchLabel.getFont().deriveFont(Font.BOLD)); - findPanel.add(searchLabel); - findPanel.add(Box.createHorizontalStrut(3)); - - findPanel.add(findField); - findPanel.add(Box.createRigidArea(new Dimension(5, 0))); - searchLabel.setLabelFor(findField); externalPanel.add(undockedToolbar, BorderLayout.NORTH); externalPanel.add(nameTreeAndMainPanelSplit, BorderLayout.CENTER); @@ -2455,8 +2534,8 @@ public class LogPanel extends DockablePa tableRuleMediator.setFindRule(null); searchRuleMediator.setFindRule(null); //reset background color in case we were previously an invalid expression - findField.setBackground(UIManager.getColor("TextField.background")); - findField.setToolTipText( + findCombo.setBackground(UIManager.getColor("TextField.background")); + findCombo.setToolTipText( "Enter expression - right click or ctrl-space for menu"); currentSearchMatchCount = 0; currentFindRuleText = null; @@ -2474,7 +2553,7 @@ public class LogPanel extends DockablePa } currentFindRuleText = ruleText; try { - findField.setToolTipText( + findCombo.setToolTipText( "Enter expression - right click or ctrl-space for menu"); findRule = ExpressionRule.getRule(ruleText); currentSearchMatchCount = tableModel.updateEventsWithFindRule(findRule); @@ -2483,15 +2562,15 @@ public class LogPanel extends DockablePa tableRuleMediator.setFindRule(findRule); searchRuleMediator.setFindRule(findRule); //valid expression, reset background color in case we were previously an invalid expression - findField.setBackground(UIManager.getColor("TextField.background")); + findCombo.setBackground(UIManager.getColor("TextField.background")); statusBar.setSearchMatchCount(currentSearchMatchCount, getIdentifier()); if (isSearchResultsVisible()) { showSearchResults(); } } catch (IllegalArgumentException re) { findRule = null; - findField.setToolTipText(re.getMessage()); - findField.setBackground(ChainsawConstants.INVALID_EXPRESSION_BACKGROUND); + findCombo.setToolTipText(re.getMessage()); + findCombo.setBackground(ChainsawConstants.INVALID_EXPRESSION_BACKGROUND); colorizer.setFindRule(null); tableRuleMediator.setFindRule(null); searchRuleMediator.setFindRule(null); @@ -2510,8 +2589,19 @@ public class LogPanel extends DockablePa private void hideSearchResults() { if (searchResultsDisplayed) { detailPanel.removeAll(); + JPanel leftSpacePanel = new JPanel(); + Integer scrollBarWidth = (Integer) UIManager.get("ScrollBar.width"); + leftSpacePanel.setPreferredSize(new Dimension(scrollBarWidth.intValue() -4, -1)); + + JPanel rightSpacePanel = new JPanel(); + rightSpacePanel.setPreferredSize(new Dimension(scrollBarWidth.intValue() -4, -1)); + detailPanel.add(detailToolbar, BorderLayout.NORTH); detailPanel.add(detailPane, BorderLayout.CENTER); + + detailPanel.add(leftSpacePanel, BorderLayout.WEST); + detailPanel.add(rightSpacePanel, BorderLayout.EAST); + detailPanel.invalidate(); detailPanel.revalidate(); detailPanel.repaint(); @@ -2744,91 +2834,15 @@ public class LogPanel extends DockablePa toggleScrollToBottomButton.setText(""); toolbar.add(toggleScrollToBottomButton); toolbar.addSeparator(); - - findField = new JTextField(); - Dimension findSize = new Dimension(260, 22); - findField.setPreferredSize(findSize); - findField.setMaximumSize(findSize); - findField.setMinimumSize(findSize); - findPanel.setAlignmentY(Component.CENTER_ALIGNMENT); - findField.setAlignmentY(Component.CENTER_ALIGNMENT); - findField.addActionListener(new ActionListener(){ - public void actionPerformed(ActionEvent e) { - findNext(); - } - }); - findField.addKeyListener( - new ExpressionRuleContext(filterModel, findField)); - final Action undockedFindNextAction = - new AbstractAction() { - public void actionPerformed(ActionEvent e) { - findNext(); - } - }; - - undockedFindNextAction.putValue(Action.NAME, "Find next"); - undockedFindNextAction.putValue( - Action.SHORT_DESCRIPTION, - "Find the next search occurrence"); - undockedFindNextAction.putValue( - Action.SMALL_ICON, new ImageIcon(ChainsawIcons.DOWN)); - - SmallButton undockedFindNextButton = - new SmallButton(undockedFindNextAction); - - undockedFindNextButton.setAction(undockedFindNextAction); - undockedFindNextButton.setText(""); - undockedFindNextButton.getActionMap().put( - undockedFindNextAction.getValue(Action.NAME), undockedFindNextAction); - undockedFindNextButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put( - KeyStroke.getKeyStroke("F3"), - undockedFindNextAction.getValue(Action.NAME)); - - final Action undockedFindPreviousAction = - new AbstractAction() { + findCombo.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { - findPrevious(); + //comboboxchanged event received when text is modified in the field..when enter is pressed, it's comboboxedited + if (e.getActionCommand().equalsIgnoreCase("comboBoxEdited")) { + findNext(); + } } - }; - - undockedFindPreviousAction.putValue(Action.NAME, "Find previous"); - undockedFindPreviousAction.putValue( - Action.SHORT_DESCRIPTION, - "Find the previous search occurrence"); - undockedFindPreviousAction.putValue( - Action.SMALL_ICON, new ImageIcon(ChainsawIcons.UP)); - - SmallButton undockedFindPreviousButton = - new SmallButton(undockedFindPreviousAction); - - undockedFindPreviousButton.setAction(undockedFindPreviousAction); - undockedFindPreviousButton.setText(""); - undockedFindPreviousButton.getActionMap().put( - undockedFindPreviousAction.getValue(Action.NAME), - undockedFindPreviousAction); - undockedFindPreviousButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put( - KeyStroke.getKeyStroke(KeyEvent.VK_F3, InputEvent.SHIFT_MASK), - undockedFindPreviousAction.getValue(Action.NAME)); - - Dimension findPanelSize = new Dimension(310, 30); - findPanel.setPreferredSize(findPanelSize); - findPanel.setMaximumSize(findPanelSize); - findPanel.setMinimumSize(findPanelSize); - findField.setPreferredSize(findSize); - findField.setMaximumSize(findSize); - findField.setMinimumSize(findSize); - findPanel.setAlignmentY(Component.CENTER_ALIGNMENT); - findField.setAlignmentY(Component.CENTER_ALIGNMENT); - - toolbar.add(findPanel); - toolbar.addSeparator(new Dimension(7, 5)); - - toolbar.add(undockedFindNextButton); - toolbar.add(undockedFindPreviousButton); - - toolbar.addSeparator(); - + }); Action redockAction = new AbstractAction("", ChainsawIcons.ICON_DOCK) { public void actionPerformed(ActionEvent arg0) { @@ -2927,7 +2941,8 @@ public class LogPanel extends DockablePa * */ public void findNext() { - updateFindRule(findField.getText()); + Object item = findCombo.getSelectedItem(); + updateFindRule(item == null ? null: item.toString()); if (findRule != null) { EventQueue.invokeLater(new Runnable() { @@ -2943,10 +2958,10 @@ public class LogPanel extends DockablePa if (nextRow > -1) { table.scrollToRow(nextRow); - findField.setToolTipText("Enter an expression"); + findCombo.setToolTipText("Enter an expression"); } } catch (IllegalArgumentException iae) { - findField.setToolTipText(iae.getMessage()); + findCombo.setToolTipText(iae.getMessage()); colorizer.setFindRule(null); tableRuleMediator.setFindRule(null); searchRuleMediator.setFindRule(null); @@ -2962,7 +2977,8 @@ public class LogPanel extends DockablePa * */ public void findPrevious() { - updateFindRule(findField.getText()); + Object item = findCombo.getSelectedItem(); + updateFindRule(item == null ? null: item.toString()); if (findRule != null) { EventQueue.invokeLater(new Runnable() { @@ -2977,10 +2993,10 @@ public class LogPanel extends DockablePa if (previousRow > -1) { table.scrollToRow(previousRow); - findField.setToolTipText("Enter an expression"); + findCombo.setToolTipText("Enter an expression"); } } catch (IllegalArgumentException iae) { - findField.setToolTipText(iae.getMessage()); + findCombo.setToolTipText(iae.getMessage()); } } }); @@ -3098,10 +3114,6 @@ public class LogPanel extends DockablePa repaint(); } - public JTextField getFindTextField() { - return findField; - } - /** * Iterate over all values in the column and return the longest width * @@ -3217,26 +3229,26 @@ public class LogPanel extends DockablePa } /** - * This class receives notification when the Refine focus text field is - * updated, where a backgrounh thread periodically wakes up and checks if + * This class receives notification when the Refine focus or find field is + * updated, where a background thread periodically wakes up and checks if * they have stopped typing yet. This ensures that the filtering of the * model is not done for every single character typed. * * @author Paul Smith psmith */ - private final class DelayedFilterTextDocumentListener + private final class DelayedTextDocumentListener implements DocumentListener { private static final long CHECK_PERIOD = 1000; - private final JTextField filterText; + private final JTextField textField; private long lastTimeStamp = System.currentTimeMillis(); private final Thread delayThread; private final String defaultToolTip; - private String lastFilterText = ""; + private String lastText = ""; - private DelayedFilterTextDocumentListener(final JTextField filterText) { + private DelayedTextDocumentListener(final JTextField textFeld) { super(); - this.filterText = filterText; - this.defaultToolTip = filterText.getToolTipText(); + this.textField = textFeld; + this.defaultToolTip = textFeld.getToolTipText(); this.delayThread = new Thread( @@ -3258,13 +3270,13 @@ public class LogPanel extends DockablePa // they stopped typing recently, but have stopped for at least // 1 sample period. lets apply the filter // logger.debug("Typed something recently applying filter"); - if (!(filterText.getText().trim().equals(lastFilterText.trim()))) { - lastFilterText = filterText.getText(); + if (!(textFeld.getText().trim().equals(lastText.trim()))) { + lastText = textFeld.getText(); EventQueue.invokeLater(new Runnable() { public void run() { - setFilter(); + setFilter(); } }); } @@ -3319,23 +3331,45 @@ public class LogPanel extends DockablePa * Update refinement rule based on the entered expression. */ private void setFilter() { - if (filterText.getText().trim().equals("")) { + if (textField.getText().trim().equals("")) { //reset background color in case we were previously an invalid expression - filterText.setBackground(UIManager.getColor("TextField.background")); + textField.setBackground(UIManager.getColor("TextField.background")); tableRuleMediator.setFilterRule(null); searchRuleMediator.setFilterRule(null); - filterText.setToolTipText(defaultToolTip); + textField.setToolTipText(defaultToolTip); + } else { + try { + tableRuleMediator.setFilterRule(ExpressionRule.getRule(textField.getText())); + searchRuleMediator.setFilterRule(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 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.setFilterRule(ExpressionRule.getRule(filterText.getText())); - searchRuleMediator.setFilterRule(ExpressionRule.getRule(filterText.getText())); - filterText.setToolTipText(defaultToolTip); + 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 - filterText.setBackground(UIManager.getColor("TextField.background")); + textField.setBackground(UIManager.getColor("TextField.background")); } catch (IllegalArgumentException iae) { //invalid expression, change background of the field - filterText.setToolTipText(iae.getMessage()); - filterText.setBackground(ChainsawConstants.INVALID_EXPRESSION_BACKGROUND); + textField.setToolTipText(iae.getMessage()); + textField.setBackground(ChainsawConstants.INVALID_EXPRESSION_BACKGROUND); } } } @@ -4142,7 +4176,7 @@ public class LogPanel extends DockablePa } } - static class AutoFilterComboBox extends JComboBox { + class AutoFilterComboBox extends JComboBox { private boolean bypassFiltering; private List allEntries = new ArrayList(); private List displayedEntries = new ArrayList(); @@ -4151,13 +4185,7 @@ public class LogPanel extends DockablePa private final JTextField textField = new JTextField(); private String lastTextToMatch; - public AutoFilterComboBox(Collection entries) { - if (entries != null) { - for (Iterator iter=entries.iterator();iter.hasNext();) { - Object nextObject = iter.next(); - model.addElement(nextObject); - } - } + public AutoFilterComboBox() { setModel(model); setEditor(new AutoFilterEditor()); ((JTextField)getEditor().getEditorComponent()).getDocument().addDocumentListener(new AutoFilterDocumentListener()); @@ -4290,6 +4318,7 @@ public class LogPanel extends DockablePa //assuming removal is from displayed list..remove from full list Object obj = displayedEntries.get(index); allEntries.remove(obj); + displayedEntries.remove(obj); fireContentsChanged(this, 0, displayedEntries.size()); bypassFiltering = false; refilter(); Modified: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LoggingEventWrapper.java URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LoggingEventWrapper.java?rev=1023677&r1=1023676&r2=1023677&view=diff ============================================================================== --- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LoggingEventWrapper.java (original) +++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LoggingEventWrapper.java Mon Oct 18 07:46:19 2010 @@ -108,9 +108,17 @@ public class LoggingEventWrapper { if (backgroundColor != null && foregroundColor != null) { this.colorRuleBackground = backgroundColor; this.colorRuleForeground = foregroundColor; + if (syncWrapper != null) { + syncWrapper.colorRuleBackground = this.colorRuleBackground; + syncWrapper.colorRuleForeground = this.colorRuleForeground; + } } else { this.colorRuleBackground = ChainsawConstants.COLOR_DEFAULT_BACKGROUND; this.colorRuleForeground = ChainsawConstants.COLOR_DEFAULT_FOREGROUND; + if (syncWrapper != null) { + syncWrapper.colorRuleBackground = this.colorRuleBackground; + syncWrapper.colorRuleForeground = this.colorRuleForeground; + } } }