View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  package org.apache.log4j.chainsaw;
    18
    19  import java.awt.BorderLayout;
    20  import java.awt.Component;
    21  import java.awt.Dimension;
    22  import java.awt.event.ActionEvent;
    23  import java.awt.event.ActionListener;
    24  import java.awt.event.MouseAdapter;
    25  import java.awt.event.MouseEvent;
    26  import java.beans.PropertyChangeEvent;
    27  import java.beans.PropertyChangeListener;
    28  import java.util.ArrayList;
    29  import java.util.Enumeration;
    30  import java.util.Iterator;
    31  import java.util.List;
    32
    33  import javax.swing.BorderFactory;
    34  import javax.swing.Box;
    35  import javax.swing.BoxLayout;
    36  import javax.swing.ButtonGroup;
    37  import javax.swing.JButton;
    38  import javax.swing.JCheckBox;
    39  import javax.swing.JEditorPane;
    40  import javax.swing.JFrame;
    41  import javax.swing.JLabel;
    42  import javax.swing.JList;
    43  import javax.swing.JPanel;
    44  import javax.swing.JRadioButton;
    45  import javax.swing.JScrollPane;
    46  import javax.swing.JTextField;
    47  import javax.swing.SwingConstants;
    48  import javax.swing.table.TableColumn;
    49  import javax.swing.tree.DefaultMutableTreeNode;
    50  import javax.swing.tree.DefaultTreeModel;
    51  import javax.swing.tree.TreeModel;
    52
    53  import org.apache.log4j.LogManager;
    54  import org.apache.log4j.Logger;
    55
    56
    57  /**
    58   * GUI panel used to manipulate the PreferenceModel for a Log Panel
    59   *
    60   * @author Paul Smith
    61   */
    62  public class LogPanelPreferencePanel extends AbstractPreferencePanel
    63  {
    64    //~ Instance fields =========================================================
    65
    66    private final LogPanelPreferenceModel preferenceModel;
    67    private final ModifiableListModel columnListModel = new ModifiableListModel();
    68    private static final Logger logger = LogManager.getLogger(LogPanelPreferencePanel.class);
    69    private ApplicationPreferenceModel appPreferenceModel;
    70
    71    //~ Constructors ============================================================
    72
    73    public LogPanelPreferencePanel(LogPanelPreferenceModel model, ApplicationPreferenceModel appModel)
    74    {
    75      preferenceModel = model;
    76      appPreferenceModel = appModel;
    77      initComponents();
    78
    79      getOkButton().addActionListener(new ActionListener()
    80        {
    81          public void actionPerformed(ActionEvent e)
    82          {
    83            hidePanel();
    84          }
    85        });
    86
    87      getCancelButton().addActionListener(new ActionListener()
    88        {
    89          public void actionPerformed(ActionEvent e)
    90          {
    91            hidePanel();
    92          }
    93        });
    94      }
    95
    96    //~ Methods =================================================================
    97
    98    /**
    99     * DOCUMENT ME!
    100    *
    101    * @param args DOCUMENT ME!
    102    */
    103   public static void main(String[] args)
    104   {
    105     JFrame f = new JFrame("Preferences Panel Test Bed");
    106     LogPanelPreferenceModel model = new LogPanelPreferenceModel();
    107     ApplicationPreferenceModel appModel = new ApplicationPreferenceModel();
    108     LogPanelPreferencePanel panel = new LogPanelPreferencePanel(model, appModel);
    109     f.getContentPane().add(panel);
    110
    111     model.addPropertyChangeListener(new PropertyChangeListener()
    112       {
    113         public void propertyChange(PropertyChangeEvent evt)
    114         {
    115           logger.warn(evt.toString());
    116         }
    117       });
    118     panel.setOkCancelActionListener(new ActionListener()
    119       {
    120         public void actionPerformed(ActionEvent e)
    121         {
    122           System.exit(1);
    123         }
    124       });
    125
    126     f.setSize(640, 480);
    127     f.setVisible(true);
    128   }
    129
    130   protected TreeModel createTreeModel()
    131   {
    132     final DefaultMutableTreeNode rootNode =
    133       new DefaultMutableTreeNode("Preferences");
    134     DefaultTreeModel model = new DefaultTreeModel(rootNode);
    135
    136     DefaultMutableTreeNode visuals =
    137       new DefaultMutableTreeNode(new VisualsPrefPanel());
    138     DefaultMutableTreeNode formatting =
    139       new DefaultMutableTreeNode(new FormattingPanel());
    140     DefaultMutableTreeNode columns =
    141       new DefaultMutableTreeNode(new ColumnSelectorPanel());
    142
    143     rootNode.add(visuals);
    144     rootNode.add(formatting);
    145     rootNode.add(columns);
    146
    147     return model;
    148   }
    149
    150   //~ Inner Classes ===========================================================
    151
    152   /**
    153    * Allows the user to choose which columns to display.
    154    *
    155    * @author Paul Smith
    156    *
    157    */
    158   public class ColumnSelectorPanel extends BasicPrefPanel
    159   {
    160     //~ Constructors ==========================================================
    161
    162     ColumnSelectorPanel()
    163     {
    164       super("Columns");
    165       initComponents();
    166     }
    167
    168     //~ Methods ===============================================================
    169
    170     private void initComponents()
    171     {
    172       setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
    173
    174       Box columnBox = new Box(BoxLayout.Y_AXIS);
    175
    176       //		columnBox.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Displayed Columns"));
    177       final JList columnList = new JList();
    178       columnList.setVisibleRowCount(17);
    179
    180       for (
    181         Iterator iter = preferenceModel.getColumns().iterator();
    182           iter.hasNext();)
    183       {
    184           TableColumn col = (TableColumn)iter.next();
    185           Enumeration enumeration = columnListModel.elements();
    186           boolean found = false;
    187           while (enumeration.hasMoreElements()) {
    188               TableColumn thisCol = (TableColumn) enumeration.nextElement();
    189               if (thisCol.getHeaderValue().equals(col.getHeaderValue())) {
    190                   found = true;
    191               }
    192           }
    193             if (!found) {
    194               columnListModel.addElement(col);
    195             }
    196       }
    197
    198       columnList.setModel(columnListModel);
    199
    200       CheckListCellRenderer cellRenderer = new CheckListCellRenderer()
    201         {
    202           protected boolean isSelected(Object value)
    203           {
    204             return LogPanelPreferencePanel.this.preferenceModel.isColumnVisible((TableColumn)
    205               value);
    206           }
    207         };
    208
    209       columnList.addMouseListener(new MouseAdapter()
    210         {
    211           public void mouseClicked(MouseEvent e)
    212           {
    213               int i = columnList.locationToIndex(e.getPoint());
    214
    215               if (i >= 0)
    216               {
    217                 Object column = columnListModel.get(i);
    218                 preferenceModel.toggleColumn(((TableColumn)column));
    219               }
    220           }
    221         });
    222       JButton setAsDefaultsButton = new JButton("Use selected columns as default visible columns");
    223       setAsDefaultsButton.addActionListener(new ActionListener() {
    224         public void actionPerformed(ActionEvent actionEvent) {
    225           List selectedColumns = new ArrayList();
    226           for (int i = 0;i<columnListModel.getSize();i++) {
    227             if (preferenceModel.isColumnVisible((TableColumn) columnListModel.get(i))) {
    228               selectedColumns.add(((TableColumn)columnListModel.get(i)).getHeaderValue());
    229             }
    230           }
    231           appPreferenceModel.setDefaultColumnNames(selectedColumns);
    232         }
    233       });
    234       columnList.setCellRenderer(cellRenderer);
    235       columnBox.add(new JScrollPane(columnList));
    236       columnBox.add(Box.createVerticalStrut(5));
    237       columnBox.add(setAsDefaultsButton);
    238       add(columnBox);
    239       add(Box.createVerticalGlue());
    240     }
    241   }
    242
    243   /**
    244    * Provides preference gui's for all the Formatting options
    245    * available for the columns etc.
    246    */
    247   private class FormattingPanel extends BasicPrefPanel
    248   {
    249     //~ Instance fields =======================================================
    250
    251     private JTextField customFormatText = new JTextField("", 10);
    252     private JTextField loggerPrecision = new JTextField(10);
    253     private JRadioButton rdCustom = new JRadioButton("Custom Format ");
    254     private final JRadioButton rdISO =
    255       new JRadioButton(
    256         "<html><b>Fast</b> ISO 8601 format (yyyy-MM-dd HH:mm:ss) </html>");
    257     private final JTextField timeZone = new JTextField(10);
    258     private final JRadioButton rdLevelIcons = new JRadioButton("Icons ");
    259     private final JRadioButton rdLevelText = new JRadioButton("Text ");
    260     private JRadioButton rdLast;
    261
    262     //~ Constructors ==========================================================
    263
    264     private FormattingPanel()
    265     {
    266       super("Formatting");
    267       this.initComponents();
    268       setupListeners();
    269     }
    270
    271     //~ Methods ===============================================================
    272
    273     private void initComponents()
    274     {
    275       setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
    276
    277       JPanel dateFormatPanel = new JPanel();
    278       dateFormatPanel.setLayout(new BoxLayout(dateFormatPanel, BoxLayout.Y_AXIS));
    279       dateFormatPanel.setBorder(
    280         BorderFactory.createTitledBorder(
    281           BorderFactory.createEtchedBorder(), "Timestamp"));
    282
    283       ButtonGroup bgDateFormat = new ButtonGroup();
    284
    285       rdISO.setSelected(preferenceModel.isUseISO8601Format());
    286
    287       rdISO.setHorizontalTextPosition(SwingConstants.RIGHT);
    288       rdISO.setAlignmentX(Component.LEFT_ALIGNMENT);
    289
    290       bgDateFormat.add(rdISO);
    291       dateFormatPanel.add(rdISO);
    292
    293       for (
    294         Iterator iter = LogPanelPreferenceModel.DATE_FORMATS.iterator();
    295           iter.hasNext();)
    296       {
    297         final String format = (String) iter.next();
    298         final JRadioButton rdFormat = new JRadioButton(format);
    299         rdFormat.setHorizontalTextPosition(SwingConstants.RIGHT);
    300         rdFormat.setAlignmentX(Component.LEFT_ALIGNMENT);
    301
    302         rdFormat.addActionListener(new ActionListener()
    303           {
    304             public void actionPerformed(ActionEvent e)
    305             {
    306               preferenceModel.setDateFormatPattern(format);
    307               customFormatText.setEnabled(rdCustom.isSelected());
    308               rdLast = rdFormat;
    309             }
    310           });
    311         //update based on external changes to dateformatpattern (column context
    312         //menu)
    313         preferenceModel.addPropertyChangeListener(
    314           "dateFormatPattern", new PropertyChangeListener()
    315           {
    316             public void propertyChange(PropertyChangeEvent evt)
    317             {
    318               rdFormat.setSelected(
    319                 preferenceModel.getDateFormatPattern().equals(format));
    320               rdLast = rdFormat;
    321             }
    322           });
    323
    324         dateFormatPanel.add(rdFormat);
    325         bgDateFormat.add(rdFormat);
    326       }
    327
    328       customFormatText.setPreferredSize(new Dimension(100, 20));
    329       customFormatText.setMaximumSize(customFormatText.getPreferredSize());
    330       customFormatText.setMinimumSize(customFormatText.getPreferredSize());
    331       customFormatText.setEnabled(false);
    332
    333       bgDateFormat.add(rdCustom);
    334       rdCustom.setSelected(preferenceModel.isCustomDateFormat());
    335
    336       // add a custom date format
    337       if (preferenceModel.isCustomDateFormat())
    338       {
    339         customFormatText.setText(preferenceModel.getDateFormatPattern());
    340         customFormatText.setEnabled(true);
    341       }
    342
    343       JPanel customPanel = new JPanel();
    344       customPanel.setLayout(new BoxLayout(customPanel, BoxLayout.X_AXIS));
    345       customPanel.add(rdCustom);
    346       customPanel.add(customFormatText);
    347       customPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
    348
    349       dateFormatPanel.add(customPanel);
    350       dateFormatPanel.add(Box.createVerticalStrut(5));
    351
    352       JLabel dateFormatLabel = new JLabel("Time zone of events (or blank for local time zone");
    353       dateFormatPanel.add(dateFormatLabel);
    354
    355       timeZone.setMaximumSize(timeZone.getPreferredSize());
    356       dateFormatPanel.add(Box.createVerticalStrut(5));
    357       dateFormatPanel.add(timeZone);
    358
    359       add(dateFormatPanel);
    360
    361       JPanel levelFormatPanel = new JPanel();
    362       levelFormatPanel.setLayout(
    363         new BoxLayout(levelFormatPanel, BoxLayout.Y_AXIS));
    364       levelFormatPanel.setBorder(
    365         BorderFactory.createTitledBorder(
    366           BorderFactory.createEtchedBorder(), "Level"));
    367       levelFormatPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
    368
    369       ButtonGroup bgLevel = new ButtonGroup();
    370       bgLevel.add(rdLevelIcons);
    371       bgLevel.add(rdLevelText);
    372
    373       rdLevelIcons.setSelected(preferenceModel.isLevelIcons());
    374
    375       levelFormatPanel.add(rdLevelIcons);
    376       levelFormatPanel.add(rdLevelText);
    377
    378       add(levelFormatPanel);
    379
    380       JPanel loggerFormatPanel = new JPanel();
    381       loggerFormatPanel.setLayout(
    382         new BoxLayout(loggerFormatPanel, BoxLayout.Y_AXIS));
    383       loggerFormatPanel.setBorder(
    384         BorderFactory.createTitledBorder(
    385           BorderFactory.createEtchedBorder(), "Logger"));
    386       loggerFormatPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
    387
    388       loggerFormatPanel.add(Box.createVerticalStrut(3));
    389
    390       final JLabel precisionLabel =
    391         new JLabel("Number of package levels to hide (or blank to display full logger)");
    392
    393       loggerFormatPanel.add(precisionLabel);
    394       loggerFormatPanel.add(Box.createVerticalStrut(5));
    395
    396       loggerPrecision.setMaximumSize(loggerPrecision.getPreferredSize());
    397       loggerFormatPanel.add(loggerPrecision);
    398
    399       add(loggerFormatPanel);
    400     }
    401
    402     /*
    403      * Restore text fields to current model values
    404      */
    405     private void reset() {
    406
    407     	if (preferenceModel.isCustomDateFormat()) {
    408     		customFormatText.setText(preferenceModel.getDateFormatPattern());
    409     	} else {
    410     		if (rdLast != null) {
    411     			rdLast.setSelected(true);
    412     		}
    413     		customFormatText.setEnabled(false);
    414     	}
    415
    416     	loggerPrecision.setText(preferenceModel.getLoggerPrecision());
    417     	timeZone.setText(preferenceModel.getTimeZone());
    418     }
    419
    420     /*
    421      * Commit text fields to model
    422      */
    423     private void commit() {
    424     	if (rdCustom.isSelected()) {
    425     		preferenceModel.setDateFormatPattern(customFormatText.getText());
    426     	}
    427     	preferenceModel.setLoggerPrecision(loggerPrecision.getText());
    428     	preferenceModel.setTimeZone(timeZone.getText());
    429     }
    430
    431     /**
    432      * DOCUMENT ME!
    433     */
    434     private void setupListeners()
    435     {
    436       getOkButton().addActionListener(new ActionListener() {
    437     	  public void actionPerformed(ActionEvent evt) {
    438     		  commit();
    439     	  }
    440       });
    441
    442       getCancelButton().addActionListener(new ActionListener() {
    443     	  public void actionPerformed(ActionEvent evt) {
    444     		  reset();
    445     	  }
    446       });
    447
    448     	  rdCustom.addActionListener(new ActionListener()
    449         {
    450           public void actionPerformed(ActionEvent e)
    451           {
    452             customFormatText.setEnabled(rdCustom.isSelected());
    453             customFormatText.grabFocus();
    454           }
    455         });
    456
    457       //a second?? listener for dateformatpattern
    458       preferenceModel.addPropertyChangeListener(
    459         "dateFormatPattern", new PropertyChangeListener()
    460         {
    461           public void propertyChange(PropertyChangeEvent evt)
    462           {
    463             /**
    464              * we need to make sure we are not reacting to the user typing, so only do this
    465              * if the text box is not the same as the model
    466              */
    467             if (
    468               preferenceModel.isCustomDateFormat()
    469                 && !customFormatText.getText().equals(
    470                   evt.getNewValue().toString()))
    471             {
    472               customFormatText.setText(preferenceModel.getDateFormatPattern());
    473               rdCustom.setSelected(true);
    474               customFormatText.setEnabled(true);
    475             }
    476             else
    477             {
    478               rdCustom.setSelected(false);
    479             }
    480           }
    481         });
    482
    483       rdISO.addActionListener(new ActionListener()
    484         {
    485           public void actionPerformed(ActionEvent e)
    486           {
    487             preferenceModel.setDateFormatPattern("ISO8601");
    488             customFormatText.setEnabled(rdCustom.isSelected());
    489             rdLast = rdISO;
    490           }
    491         });
    492       preferenceModel.addPropertyChangeListener(
    493         "dateFormatPattern", new PropertyChangeListener()
    494         {
    495           public void propertyChange(PropertyChangeEvent evt)
    496           {
    497             rdISO.setSelected(preferenceModel.isUseISO8601Format());
    498             rdLast = rdISO;
    499           }
    500         });
    501       preferenceModel.addPropertyChangeListener(
    502           "dateFormatTimeZone", new PropertyChangeListener() {
    503               public void propertyChange(PropertyChangeEvent evt) {
    504                   timeZone.setText(preferenceModel.getTimeZone());
    505               }
    506           }
    507       );
    508
    509       ActionListener levelIconListener = new ActionListener()
    510         {
    511           public void actionPerformed(ActionEvent e)
    512           {
    513             preferenceModel.setLevelIcons(rdLevelIcons.isSelected());
    514           }
    515         };
    516
    517       rdLevelIcons.addActionListener(levelIconListener);
    518       rdLevelText.addActionListener(levelIconListener);
    519
    520       preferenceModel.addPropertyChangeListener(
    521         "levelIcons", new PropertyChangeListener()
    522         {
    523           public void propertyChange(PropertyChangeEvent evt)
    524           {
    525             boolean value = ((Boolean) evt.getNewValue()).booleanValue();
    526             rdLevelIcons.setSelected(value);
    527             rdLevelText.setSelected(!value);
    528           }
    529         });
    530     }
    531   }
    532
    533   /**
    534    * DOCUMENT ME!
    535    *
    536    * @author $author$
    537    * @version $Revision$, $Date$
    538    *
    539    * @author psmith
    540    *
    541    */
    542   private class VisualsPrefPanel extends BasicPrefPanel
    543   {
    544     //~ Instance fields =======================================================
    545
    546     private final JCheckBox detailPanelVisible =
    547       new JCheckBox("Show Event Detail panel");
    548
    549     private final JCheckBox loggerTreePanel =
    550       new JCheckBox("Show Logger Tree");
    551     private final JCheckBox wrapMessage = new JCheckBox("Wrap message field (display multi-line rows) ");
    552     private final JCheckBox searchResultsVisible = new JCheckBox("Display find results in details panel ");
    553     private final JCheckBox highlightSearchMatchText = new JCheckBox("Highlight find match text ");
    554     private final JCheckBox scrollToBottom =
    555       new JCheckBox("Scroll to bottom (view tracks with new events)");
    556     private final JCheckBox showMillisDeltaAsGap =
    557       new JCheckBox("Display timestamp delta between events as row gap");
    558     private final JCheckBox toolTips =
    559       new JCheckBox("Show Event Detail Tooltips");
    560     private final JCheckBox thumbnailBarToolTips =
    561       new JCheckBox("Show Thumbnail Bar Tooltips");
    562     private final JEditorPane clearTableExpression = new JEditorPane();
    563
    564     //~ Constructors ==========================================================
    565
    566     /**
    567      * Creates a new VisualsPrefPanel object.
    568     */
    569     private VisualsPrefPanel()
    570     {
    571       super("Visuals");
    572       initPanelComponents();
    573       setupListeners();
    574     }
    575
    576     //~ Methods ===============================================================
    577
    578     /**
    579      * DOCUMENT ME!
    580     */
    581     private void initPanelComponents()
    582     {
    583       JTextComponentFormatter.applySystemFontAndSize(clearTableExpression);
    584       setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
    585       toolTips.setAlignmentX(Component.LEFT_ALIGNMENT);
    586       thumbnailBarToolTips.setAlignmentX(Component.LEFT_ALIGNMENT);
    587       detailPanelVisible.setAlignmentX(Component.LEFT_ALIGNMENT);
    588       loggerTreePanel.setAlignmentX(Component.LEFT_ALIGNMENT);
    589       scrollToBottom.setAlignmentX(Component.LEFT_ALIGNMENT);
    590       showMillisDeltaAsGap.setAlignmentX(Component.LEFT_ALIGNMENT);
    591       add(toolTips);
    592       add(thumbnailBarToolTips);
    593       add(detailPanelVisible);
    594       add(loggerTreePanel);
    595       add(scrollToBottom);
    596       add(wrapMessage);
    597       add(highlightSearchMatchText);
    598       add(searchResultsVisible);
    599       add(showMillisDeltaAsGap);
    600       JPanel clearPanel = new JPanel(new BorderLayout());
    601       clearPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
    602       clearPanel.add(new JLabel("Clear all events if expression matches"), BorderLayout.NORTH);
    603       clearTableExpression.setText(preferenceModel.getClearTableExpression());
    604       clearTableExpression.setPreferredSize(new Dimension(300, 50));
    605       JPanel clearTableScrollPanel = new JPanel(new BorderLayout());
    606       clearTableScrollPanel.add(new JScrollPane(clearTableExpression), BorderLayout.NORTH);
    607       clearPanel.add(clearTableScrollPanel, BorderLayout.CENTER);
    608       add(clearPanel);
    609
    610       toolTips.setSelected(preferenceModel.isToolTips());
    611       thumbnailBarToolTips.setSelected(preferenceModel.isThumbnailBarToolTips());
    612       detailPanelVisible.setSelected(preferenceModel.isDetailPaneVisible());
    613       searchResultsVisible.setSelected(preferenceModel.isSearchResultsVisible());
    614       loggerTreePanel.setSelected(preferenceModel.isLogTreePanelVisible());
    615     }
    616
    617     /**
    618      * DOCUMENT ME!
    619     */
    620     private void setupListeners()
    621     {
    622         ActionListener wrapMessageListener = new ActionListener()
    623         {
    624             public void actionPerformed(ActionEvent e)
    625             {
    626                 preferenceModel.setWrapMessage(wrapMessage.isSelected());
    627             }
    628         };
    629
    630         wrapMessage.addActionListener(wrapMessageListener);
    631
    632         ActionListener searchResultsVisibleListener = new ActionListener()
    633         {
    634             public void actionPerformed(ActionEvent e)
    635             {
    636                 preferenceModel.setSearchResultsVisible(searchResultsVisible.isSelected());
    637             }
    638         };
    639
    640         searchResultsVisible.addActionListener(searchResultsVisibleListener);
    641
    642         ActionListener highlightSearchMatchTextListener = new ActionListener()
    643         {
    644             public void actionPerformed(ActionEvent e)
    645             {
    646                 preferenceModel.setHighlightSearchMatchText(highlightSearchMatchText.isSelected());
    647             }
    648         };
    649
    650         highlightSearchMatchText.addActionListener(highlightSearchMatchTextListener);
    651
    652         preferenceModel.addPropertyChangeListener(
    653           "wrapMessage", new PropertyChangeListener()
    654           {
    655             public void propertyChange(PropertyChangeEvent evt)
    656             {
    657               boolean value = ((Boolean) evt.getNewValue()).booleanValue();
    658               wrapMessage.setSelected(value);
    659             }
    660           });
    661
    662       preferenceModel.addPropertyChangeListener(
    663         "searchResultsVisible", new PropertyChangeListener()
    664         {
    665           public void propertyChange(PropertyChangeEvent evt)
    666           {
    667             boolean value = ((Boolean) evt.getNewValue()).booleanValue();
    668             searchResultsVisible.setSelected(value);
    669           }
    670         });
    671
    672         preferenceModel.addPropertyChangeListener(
    673           "highlightSearchMatchText", new PropertyChangeListener()
    674           {
    675             public void propertyChange(PropertyChangeEvent evt)
    676             {
    677               boolean value = ((Boolean) evt.getNewValue()).booleanValue();
    678               highlightSearchMatchText.setSelected(value);
    679             }
    680           });
    681
    682       toolTips.addActionListener(new ActionListener()
    683         {
    684           public void actionPerformed(ActionEvent e)
    685           {
    686             preferenceModel.setToolTips(toolTips.isSelected());
    687           }
    688         });
    689
    690       thumbnailBarToolTips.addActionListener(new ActionListener() {
    691           public void actionPerformed(ActionEvent e) {
    692               preferenceModel.setThumbnailBarToolTips(thumbnailBarToolTips.isSelected());
    693           }
    694       });
    695
    696       getOkButton().addActionListener(new ActionListener() {
    697           public void actionPerformed(ActionEvent e) {
    698               preferenceModel.setClearTableExpression(clearTableExpression.getText().trim());
    699           }
    700       });
    701
    702       preferenceModel.addPropertyChangeListener(
    703         "toolTips", new PropertyChangeListener()
    704         {
    705           public void propertyChange(PropertyChangeEvent evt)
    706           {
    707             boolean value = ((Boolean) evt.getNewValue()).booleanValue();
    708             toolTips.setSelected(value);
    709           }
    710         });
    711
    712     preferenceModel.addPropertyChangeListener(
    713       "thumbnailBarToolTips", new PropertyChangeListener()
    714       {
    715         public void propertyChange(PropertyChangeEvent evt)
    716         {
    717           boolean value = ((Boolean) evt.getNewValue()).booleanValue();
    718           thumbnailBarToolTips.setSelected(value);
    719         }
    720       });
    721
    722       detailPanelVisible.addActionListener(new ActionListener()
    723         {
    724           public void actionPerformed(ActionEvent e)
    725           {
    726             preferenceModel.setDetailPaneVisible(detailPanelVisible.isSelected());
    727           }
    728         });
    729
    730       preferenceModel.addPropertyChangeListener(
    731         "detailPaneVisible", new PropertyChangeListener()
    732         {
    733           public void propertyChange(PropertyChangeEvent evt)
    734           {
    735             boolean value = ((Boolean) evt.getNewValue()).booleanValue();
    736             detailPanelVisible.setSelected(value);
    737           }
    738         });
    739
    740       scrollToBottom.addActionListener(new ActionListener()
    741         {
    742           public void actionPerformed(ActionEvent e)
    743           {
    744             preferenceModel.setScrollToBottom(scrollToBottom.isSelected());
    745           }
    746         });
    747
    748       showMillisDeltaAsGap.addActionListener(new ActionListener()
    749       {
    750           public void actionPerformed(ActionEvent e)
    751           {
    752               preferenceModel.setShowMillisDeltaAsGap(showMillisDeltaAsGap.isSelected());
    753           }
    754       });
    755
    756       preferenceModel.addPropertyChangeListener("showMillisDeltaAsGap", new PropertyChangeListener()
    757       {
    758           public void propertyChange(PropertyChangeEvent evt)
    759           {
    760               boolean value = ((Boolean) evt.getNewValue()).booleanValue();
    761               showMillisDeltaAsGap.setSelected(value);
    762           }
    763       });
    764       preferenceModel.addPropertyChangeListener(
    765         "scrollToBottom", new PropertyChangeListener()
    766         {
    767           public void propertyChange(PropertyChangeEvent evt)
    768           {
    769             boolean value = ((Boolean) evt.getNewValue()).booleanValue();
    770             scrollToBottom.setSelected(value);
    771           }
    772         });
    773
    774       loggerTreePanel.addActionListener(new ActionListener()
    775         {
    776           public void actionPerformed(ActionEvent e)
    777           {
    778             preferenceModel.setLogTreePanelVisible(loggerTreePanel.isSelected());
    779           }
    780         });
    781
    782       preferenceModel.addPropertyChangeListener(
    783         "logTreePanelVisible", new PropertyChangeListener()
    784         {
    785           public void propertyChange(PropertyChangeEvent evt)
    786           {
    787             boolean value = ((Boolean) evt.getNewValue()).booleanValue();
    788             loggerTreePanel.setSelected(value);
    789           }
    790         });
    791
    792       preferenceModel.addPropertyChangeListener("columns", new PropertyChangeListener() {
    793         	public void propertyChange(PropertyChangeEvent evt) {
    794       	  List cols = (List)evt.getNewValue();
    795             for (
    796           	        Iterator iter = cols.iterator();
    797           	          iter.hasNext();)
    798           	      {
    799           	        TableColumn col = (TableColumn) iter.next();
    800                     Enumeration enumeration = columnListModel.elements();
    801                     boolean found = false;
    802                     while (enumeration.hasMoreElements()) {
    803                         TableColumn thisCol = (TableColumn) enumeration.nextElement();
    804                         if (thisCol.getHeaderValue().equals(col.getHeaderValue())) {
    805                             found = true;
    806                         }
    807                     }
    808           	        if (!found) {
    809           	        	columnListModel.addElement(col);
    810           	            columnListModel.fireContentsChanged();
    811           	        }
    812           	      }
    813         }});
    814
    815         preferenceModel.addPropertyChangeListener(
    816                 "visibleColumns", new PropertyChangeListener()
    817                 {
    818                   public void propertyChange(PropertyChangeEvent evt)
    819                   {
    820                     columnListModel.fireContentsChanged();
    821                   }
    822                 });
    823
    824         preferenceModel.addPropertyChangeListener("clearTableExpression", new PropertyChangeListener()
    825         {
    826             public void propertyChange(PropertyChangeEvent evt) {
    827                 clearTableExpression.setText(((LogPanelPreferenceModel)evt.getSource()).getClearTableExpression());
    828             }
    829         });
    830     }
    831   }
    832 }