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
    18  package org.apache.log4j.chainsaw;
    19
    20  import org.apache.log4j.chainsaw.filter.FilterModel;
    21  import org.apache.log4j.chainsaw.help.HelpManager;
    22  import org.apache.log4j.chainsaw.icons.ChainsawIcons;
    23  import org.apache.log4j.chainsaw.osx.OSXIntegration;
    24  import org.apache.log4j.chainsaw.receivers.ReceiversHelper;
    25
    26  import javax.swing.*;
    27  import javax.swing.event.ChangeEvent;
    28  import javax.swing.event.ChangeListener;
    29  import java.awt.*;
    30  import java.awt.event.ActionEvent;
    31  import java.awt.event.InputEvent;
    32  import java.awt.event.KeyEvent;
    33  import java.util.ArrayList;
    34  import java.util.Collection;
    35  import java.util.List;
    36
    37
    38  /**
    39   * Encapsulates the full Toolbar, and menus and all the actions that can be performed from it.
    40   *
    41   * @author Paul Smith &lt;psmith@apache.org&gt;
    42   * @author Scott Deboy &lt;sdeboy@apache.org&gt;
    43   */
    44  class ChainsawToolBarAndMenus implements ChangeListener {
    45      private final SmallToggleButton showReceiversButton;
    46      private final Action changeModelAction;
    47      private final Action clearAction;
    48      private final Action toggleWelcomeVisibleAction;
    49      private final Action findPreviousColorizedEventAction;
    50      private final Action findNextColorizedEventAction;
    51      private final Action findNextMarkerAction;
    52      private final Action findPreviousMarkerAction;
    53      private final Action toggleMarkerAction;
    54      private final Action clearAllMarkersAction;
    55      private final Action pauseAction;
    56      private final Action showPreferencesAction;
    57      private final Action showColorPanelAction;
    58      private final Action showReceiversAction;
    59      private final Action toggleLogTreeAction;
    60      private final Action toggleScrollToBottomAction;
    61      private final Action scrollToTopAction;
    62      private final Action toggleDetailPaneAction;
    63      private final Action toggleToolbarAction;
    64      private final Action undockAction;
    65      private final Action customExpressionPanelAction;
    66      private final Collection lookAndFeelMenus = new ArrayList();
    67      private final JCheckBoxMenuItem toggleShowReceiversCheck =
    68          new JCheckBoxMenuItem();
    69      private final JCheckBoxMenuItem toggleLogTreeMenuItem =
    70          new JCheckBoxMenuItem();
    71      private final JCheckBoxMenuItem toggleScrollToBottomMenuItem =
    72          new JCheckBoxMenuItem();
    73      private final JCheckBoxMenuItem toggleDetailMenuItem =
    74          new JCheckBoxMenuItem();
    75      private final JCheckBoxMenuItem toggleCyclicMenuItem =
    76          new JCheckBoxMenuItem();
    77      private final FileMenu fileMenu;
    78      private final JCheckBoxMenuItem toggleStatusBarCheck =
    79          new JCheckBoxMenuItem();
    80      private final JMenu viewMenu = new JMenu("View");
    81      private final JMenuBar menuBar;
    82      private final JCheckBoxMenuItem menuShowWelcome = new JCheckBoxMenuItem();
    83      private final JToolBar toolbar;
    84      private final LogUI logui;
    85      private final SmallButton clearButton = new SmallButton();
    86      private final SmallToggleButton detailPaneButton = new SmallToggleButton();
    87      private final SmallToggleButton logTreePaneButton = new SmallToggleButton();
    88      private final SmallToggleButton scrollToBottomButton = new SmallToggleButton();
    89      private final SmallToggleButton pauseButton = new SmallToggleButton();
    90      private final SmallToggleButton toggleCyclicButton = new SmallToggleButton();
    91      private final Action[] logPanelSpecificActions;
    92      private final JMenu activeTabMenu = new JMenu("Current tab");
    93
    94      ChainsawToolBarAndMenus(final LogUI logui) {
    95          this.logui = logui;
    96          toolbar = new JToolBar(SwingConstants.HORIZONTAL);
    97          menuBar = new JMenuBar();
    98          fileMenu = new FileMenu(logui);
    99          toggleWelcomeVisibleAction = toggleWelcomeVisibleAction();
    100         changeModelAction = createChangeModelAction();
    101         findNextMarkerAction = createFindNextMarkerAction();
    102         findPreviousColorizedEventAction = getFindPreviousColorizedEventAction();
    103         findNextColorizedEventAction = getFindNextColorizedEventAction();
    104         findPreviousMarkerAction = createFindPreviousMarkerAction();
    105         toggleMarkerAction = createToggleMarkerAction();
    106         clearAllMarkersAction = createClearAllMarkersAction();
    107         customExpressionPanelAction = createCustomExpressionPanelAction();
    108         showPreferencesAction = createShowPreferencesAction();
    109         showColorPanelAction = createShowColorPanelAction();
    110         toggleToolbarAction = createToggleToolbarAction();
    111         toggleLogTreeAction = createToggleLogTreeAction();
    112         toggleScrollToBottomAction = createScrollToBottomAction();
    113         scrollToTopAction = createScrollToTopAction();
    114         pauseAction = createPauseAction();
    115         clearAction = createClearAction();
    116         undockAction = createUndockAction();
    117         showReceiversAction = createShowReceiversAction();
    118         showReceiversButton = new SmallToggleButton(showReceiversAction);
    119
    120         toggleDetailPaneAction = createToggleDetailPaneAction();
    121         createMenuBar();
    122         createToolbar();
    123
    124         logPanelSpecificActions =
    125             new Action[]{
    126                 pauseAction, findNextColorizedEventAction, findPreviousColorizedEventAction,
    127                 findNextMarkerAction, findPreviousMarkerAction,
    128                 toggleMarkerAction, clearAllMarkersAction, scrollToTopAction, clearAction,
    129                 fileMenu.getFileSaveAction(), toggleDetailPaneAction,
    130                 showPreferencesAction, showColorPanelAction, undockAction,
    131                 toggleLogTreeAction, toggleScrollToBottomAction, changeModelAction,
    132             };
    133
    134         logui.getApplicationPreferenceModel().addPropertyChangeListener(
    135             "statusBar",
    136             evt -> {
    137                 boolean value = (Boolean) evt.getNewValue();
    138                 toggleStatusBarCheck.setSelected(value);
    139             });
    140
    141         logui.getApplicationPreferenceModel().addPropertyChangeListener(
    142             "receivers",
    143             evt -> {
    144                 boolean value = (Boolean) evt.getNewValue();
    145                 showReceiversButton.setSelected(value);
    146                 toggleShowReceiversCheck.setSelected(value);
    147             });
    148     }
    149
    150     /**
    151      * @return
    152      */
    153     private Action createChangeModelAction() {
    154         Action action =
    155             new AbstractAction("Use Cyclic", new ImageIcon(ChainsawIcons.REFRESH)) {
    156                 public void actionPerformed(ActionEvent arg0) {
    157                     LogPanel logPanel = logui.getCurrentLogPanel();
    158                     logPanel.toggleCyclic();
    159                     scanState();
    160                 }
    161             };
    162
    163         action.putValue(
    164             Action.SHORT_DESCRIPTION, "Changes between Cyclic and Unlimited mode.");
    165
    166         return action;
    167     }
    168
    169     /**
    170      * @return
    171      */
    172     private Action createToggleLogTreeAction() {
    173         Action action =
    174             new AbstractAction("Toggle the Logger Tree Pane") {
    175                 public void actionPerformed(ActionEvent e) {
    176                     if (logui.getCurrentLogPanel() != null) {
    177                         logui.getCurrentLogPanel().toggleLogTreeVisible();
    178                     }
    179                 }
    180             };
    181
    182         action.putValue(Action.SHORT_DESCRIPTION, "Toggles the Logger Tree Pane");
    183         action.putValue("enabled", Boolean.TRUE);
    184         action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_T);
    185         action.putValue(
    186             Action.ACCELERATOR_KEY,
    187             KeyStroke.getKeyStroke(KeyEvent.VK_T, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
    188         action.putValue(
    189             Action.SMALL_ICON, new ImageIcon(ChainsawIcons.WINDOW_ICON));
    190
    191         return action;
    192     }
    193
    194     /**
    195      * @return
    196      */
    197     private Action createScrollToBottomAction() {
    198         Action action =
    199             new AbstractAction("Toggle Scroll to Bottom") {
    200                 public void actionPerformed(ActionEvent e) {
    201                     if (logui.getCurrentLogPanel() != null) {
    202                         logui.getCurrentLogPanel().toggleScrollToBottom();
    203                     }
    204                 }
    205             };
    206
    207         action.putValue(Action.SHORT_DESCRIPTION, "Toggles Scroll to Bottom");
    208         action.putValue("enabled", Boolean.TRUE);
    209         action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_B);
    210         action.putValue(
    211             Action.ACCELERATOR_KEY,
    212             KeyStroke.getKeyStroke(KeyEvent.VK_B, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
    213         action.putValue(
    214             Action.SMALL_ICON, new ImageIcon(ChainsawIcons.SCROLL_TO_BOTTOM));
    215
    216         return action;
    217     }
    218
    219     private Action createScrollToTopAction() {
    220         Action action =
    221             new AbstractAction("Scroll to top") {
    222                 public void actionPerformed(ActionEvent e) {
    223                     if (logui.getCurrentLogPanel() != null) {
    224                         logui.getCurrentLogPanel().scrollToTop();
    225                     }
    226                 }
    227             };
    228
    229         action.putValue(Action.SHORT_DESCRIPTION, "Scroll to top");
    230         action.putValue("enabled", Boolean.TRUE);
    231         action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_T);
    232         action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_A, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
    233
    234         return action;
    235     }
    236
    237     private Action createFindNextMarkerAction() {
    238         Action action =
    239             new AbstractAction("Find next marker") {
    240                 public void actionPerformed(ActionEvent e) {
    241                     if (logui.getCurrentLogPanel() != null) {
    242                         logui.getCurrentLogPanel().findNextMarker();
    243                     }
    244                 }
    245             };
    246
    247         action.putValue(Action.SHORT_DESCRIPTION, "Find the next marker from the current location");
    248         action.putValue("enabled", Boolean.TRUE);
    249         action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_N);
    250         action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("F2"));
    251
    252         return action;
    253     }
    254
    255     private Action createFindPreviousMarkerAction() {
    256         Action action =
    257             new AbstractAction("Find previous marker") {
    258                 public void actionPerformed(ActionEvent e) {
    259                     if (logui.getCurrentLogPanel() != null) {
    260                         logui.getCurrentLogPanel().findPreviousMarker();
    261                     }
    262                 }
    263             };
    264
    265         action.putValue(Action.SHORT_DESCRIPTION, "Find the previous marker from the current location");
    266         action.putValue("enabled", Boolean.TRUE);
    267         action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_P);
    268         action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F2, InputEvent.SHIFT_MASK));
    269
    270         return action;
    271     }
    272
    273     private Action createToggleMarkerAction() {
    274         Action action =
    275             new AbstractAction("Toggle marker") {
    276                 public void actionPerformed(ActionEvent e) {
    277                     if (logui.getCurrentLogPanel() != null) {
    278                         logui.getCurrentLogPanel().toggleMarker();
    279                     }
    280                 }
    281             };
    282
    283         action.putValue(Action.SHORT_DESCRIPTION, "Toggle marker for selected row");
    284         action.putValue("enabled", Boolean.TRUE);
    285         action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_T);
    286         action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F2, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
    287
    288         return action;
    289     }
    290
    291     private Action createClearAllMarkersAction() {
    292         Action action =
    293             new AbstractAction("Clear all markers") {
    294                 public void actionPerformed(ActionEvent e) {
    295                     if (logui.getCurrentLogPanel() != null) {
    296                         logui.getCurrentLogPanel().clearAllMarkers();
    297                     }
    298                 }
    299             };
    300
    301         action.putValue(Action.SHORT_DESCRIPTION, "Removes all markers");
    302         action.putValue("enabled", Boolean.TRUE);
    303         action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_R);
    304         action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F2, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() | InputEvent.SHIFT_MASK));
    305
    306         return action;
    307     }
    308
    309     /**
    310      * DOCUMENT ME!
    311      */
    312     public void stateChange() {
    313         scanState();
    314     }
    315
    316     /**
    317      * DOCUMENT ME!
    318      *
    319      * @param e DOCUMENT ME!
    320      */
    321     public void stateChanged(ChangeEvent e) {
    322         scanState();
    323     }
    324
    325     JMenuBar getMenubar() {
    326         return menuBar;
    327     }
    328
    329     JToolBar getToolbar() {
    330         return toolbar;
    331     }
    332
    333     private Action createClearAction() {
    334         final Action action =
    335             new AbstractAction("Clear") {
    336                 public void actionPerformed(ActionEvent e) {
    337                     LogPanel logPanel = logui.getCurrentLogPanel();
    338
    339                     if (logPanel == null) {
    340                         return;
    341                     }
    342
    343                     logPanel.clearEvents();
    344                 }
    345             };
    346
    347         action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_C);
    348         action.putValue(
    349             Action.ACCELERATOR_KEY,
    350             KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
    351         action.putValue(
    352             Action.SHORT_DESCRIPTION, "Removes all the events from the current view");
    353         action.putValue(Action.SMALL_ICON, new ImageIcon(ChainsawIcons.DELETE));
    354
    355         return action;
    356     }
    357
    358     private Action toggleWelcomeVisibleAction() {
    359         final Action action =
    360             new AbstractAction() {
    361                 public void actionPerformed(ActionEvent e) {
    362                     toggleWelcomeVisibleAction.putValue(Action.NAME, "Welcome tab");
    363                     if (menuShowWelcome.isSelected()) {
    364                         logui.addWelcomePanel();
    365                     } else {
    366                         logui.removeWelcomePanel();
    367                     }
    368                 }
    369             };
    370
    371         action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("F1"));
    372
    373         //    action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.ALT_MASK));
    374         action.putValue(Action.SHORT_DESCRIPTION, "Toggles the Welcome tab");
    375         action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_C);
    376         action.putValue(Action.NAME, "Welcome tab");
    377
    378         return action;
    379     }
    380
    381     private void createMenuBar() {
    382         JMenuItem menuItemUseRightMouse =
    383             new JMenuItem(
    384                 "Other options available via panel's right mouse button popup menu");
    385         menuItemUseRightMouse.setEnabled(false);
    386
    387         viewMenu.setMnemonic('V');
    388
    389         final JCheckBoxMenuItem showToolbarCheck =
    390             new JCheckBoxMenuItem(toggleToolbarAction);
    391         showToolbarCheck.setSelected(
    392             logui.getApplicationPreferenceModel().isToolbar());
    393
    394         logui.getApplicationPreferenceModel().addPropertyChangeListener(
    395             "toolbar",
    396             evt -> {
    397                 boolean value = (Boolean) evt.getNewValue();
    398                 showToolbarCheck.setSelected(value);
    399             });
    400
    401         menuShowWelcome.setAction(toggleWelcomeVisibleAction);
    402
    403         JCheckBoxMenuItem pause = new JCheckBoxMenuItem(pauseAction);
    404         JMenuItem menuPrefs = new JMenuItem(showPreferencesAction);
    405         menuPrefs.setText(
    406             showPreferencesAction.getValue(Action.SHORT_DESCRIPTION).toString());
    407
    408         JMenuItem menuCustomExpressionPanel =
    409             new JMenuItem(customExpressionPanelAction);
    410         menuCustomExpressionPanel.setText(
    411             customExpressionPanelAction.getValue(Action.SHORT_DESCRIPTION).toString());
    412
    413         JMenuItem menuShowColor = new JMenuItem(showColorPanelAction);
    414         menuShowColor.setText(
    415             showColorPanelAction.getValue(Action.SHORT_DESCRIPTION).toString());
    416
    417         JMenuItem menuUndock = new JMenuItem(undockAction);
    418
    419         JMenuItem showAppPrefs =
    420             new JMenuItem("Show Application-wide Preferences...");
    421
    422         showAppPrefs.addActionListener(
    423             e -> logui.showApplicationPreferences());
    424
    425         toggleDetailMenuItem.setAction(toggleDetailPaneAction);
    426         toggleDetailMenuItem.setSelected(true);
    427
    428         toggleCyclicMenuItem.setAction(changeModelAction);
    429
    430         toggleCyclicMenuItem.setSelected(true);
    431
    432         toggleLogTreeMenuItem.setAction(toggleLogTreeAction);
    433         toggleLogTreeMenuItem.setSelected(true);
    434
    435         toggleScrollToBottomMenuItem.setAction(toggleScrollToBottomAction);
    436
    437         final Action toggleStatusBarAction =
    438             new AbstractAction("Show Status bar") {
    439                 public void actionPerformed(ActionEvent arg0) {
    440                     logui.getApplicationPreferenceModel().setStatusBar(
    441                         toggleStatusBarCheck.isSelected());
    442                 }
    443             };
    444
    445         toggleStatusBarAction.putValue(
    446             Action.MNEMONIC_KEY, KeyEvent.VK_B);
    447         toggleStatusBarCheck.setAction(toggleStatusBarAction);
    448         toggleStatusBarCheck.setSelected(
    449             logui.getApplicationPreferenceModel().isStatusBar());
    450
    451         activeTabMenu.add(pause);
    452         activeTabMenu.add(toggleCyclicMenuItem);
    453         activeTabMenu.addSeparator();
    454         activeTabMenu.add(toggleDetailMenuItem);
    455         activeTabMenu.add(toggleLogTreeMenuItem);
    456         activeTabMenu.addSeparator();
    457         activeTabMenu.add(menuUndock);
    458         activeTabMenu.add(menuShowColor);
    459         activeTabMenu.add(menuPrefs);
    460
    461         activeTabMenu.addSeparator();
    462         activeTabMenu.add(new CopyEventsToClipboardAction(logui));
    463         activeTabMenu.add(new JMenuItem(clearAction));
    464
    465         activeTabMenu.addSeparator();
    466         activeTabMenu.add(new JMenuItem(toggleMarkerAction));
    467         activeTabMenu.add(new JMenuItem(findNextMarkerAction));
    468         activeTabMenu.add(new JMenuItem(findPreviousMarkerAction));
    469         activeTabMenu.add(new JMenuItem(clearAllMarkersAction));
    470
    471         activeTabMenu.add(new JMenuItem(findNextColorizedEventAction));
    472         activeTabMenu.add(new JMenuItem(findPreviousColorizedEventAction));
    473
    474         activeTabMenu.addSeparator();
    475         activeTabMenu.add(new JMenuItem(scrollToTopAction));
    476         activeTabMenu.add(toggleScrollToBottomMenuItem);
    477         activeTabMenu.add(menuItemUseRightMouse);
    478
    479         viewMenu.add(showToolbarCheck);
    480         viewMenu.add(toggleStatusBarCheck);
    481         viewMenu.add(toggleShowReceiversCheck);
    482         viewMenu.add(menuShowWelcome);
    483         viewMenu.addSeparator();
    484         viewMenu.add(menuCustomExpressionPanel);
    485
    486         if (!OSXIntegration.IS_OSX) {
    487             viewMenu.addSeparator();
    488             viewMenu.add(showAppPrefs);
    489         }
    490
    491         JMenu helpMenu = new JMenu("Help");
    492         helpMenu.setMnemonic('H');
    493
    494         JMenuItem about = new JMenuItem("About Chainsaw v2...");
    495         about.setMnemonic('A');
    496         about.addActionListener(
    497             e -> logui.showAboutBox());
    498
    499         Action startTutorial =
    500             new AbstractAction("Tutorial...", new ImageIcon(ChainsawIcons.HELP)) {
    501                 public void actionPerformed(ActionEvent e) {
    502                     logui.setupTutorial();
    503                 }
    504             };
    505
    506         startTutorial.putValue(
    507             Action.SHORT_DESCRIPTION, "Starts the tutorial process");
    508         helpMenu.add(startTutorial);
    509
    510         List knownReceivers =
    511             ReceiversHelper.getInstance().getKnownReceiverClasses();
    512         JMenu receiverHelp = new JMenu("Receiver JavaDoc");
    513
    514         for (Object knownReceiver : knownReceivers) {
    515             final Class clazz = (Class) knownReceiver;
    516             receiverHelp.add(
    517                 new AbstractAction(clazz.getName()) {
    518                     public void actionPerformed(ActionEvent arg0) {
    519                         HelpManager.getInstance().showHelpForClass(clazz);
    520                     }
    521                 });
    522         }
    523
    524         helpMenu.add(receiverHelp);
    525
    526         helpMenu.addSeparator();
    527         helpMenu.add(CommonActions.getInstance().getShowReleaseNotes());
    528         helpMenu.add(about);
    529
    530         menuBar.add(fileMenu);
    531         menuBar.add(viewMenu);
    532         menuBar.add(activeTabMenu);
    533         menuBar.add(helpMenu);
    534     }
    535
    536     private Action createPauseAction() {
    537         final Action action =
    538             new AbstractAction("Pause") {
    539                 public void actionPerformed(ActionEvent evt) {
    540                     LogPanel logPanel = logui.getCurrentLogPanel();
    541
    542                     if (logPanel == null) {
    543                         return;
    544                     }
    545
    546                     logPanel.setPaused(!logPanel.isPaused());
    547                     scanState();
    548                 }
    549             };
    550
    551         action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_P);
    552         action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("F12"));
    553         action.putValue(
    554             Action.SHORT_DESCRIPTION,
    555             "Causes incoming events for this tab to be discarded");
    556         action.putValue(Action.SMALL_ICON, new ImageIcon(ChainsawIcons.PAUSE));
    557
    558         return action;
    559     }
    560
    561     private Action createShowPreferencesAction() {
    562         Action showPreferences =
    563             new AbstractAction("", ChainsawIcons.ICON_PREFERENCES) {
    564                 public void actionPerformed(ActionEvent arg0) {
    565                     LogPanel logPanel = logui.getCurrentLogPanel();
    566
    567                     if (logPanel != null) {
    568                         logPanel.showPreferences();
    569                     }
    570                 }
    571             };
    572
    573         showPreferences.putValue(
    574             Action.SHORT_DESCRIPTION, "Tab Preferences...");
    575
    576         // TODO think of good mnemonics and HotKey for this action
    577         return showPreferences;
    578     }
    579
    580     private Action createCustomExpressionPanelAction() {
    581         final JDialog dialog = new JDialog(logui, "Define tab", true);
    582         dialog.getContentPane().add(getCustomExpressionPanel());
    583         dialog.setLocationRelativeTo(null);
    584         dialog.pack();
    585
    586         Action createExpressionPanel =
    587             new AbstractAction("", ChainsawIcons.ICON_HELP) {
    588                 public void actionPerformed(ActionEvent arg0) {
    589                     LogPanel.centerAndSetVisible(dialog);
    590                 }
    591             };
    592
    593         createExpressionPanel.putValue(
    594             Action.SHORT_DESCRIPTION, "Create tab from expression...   ");
    595
    596         // TODO think of good mnemonics and HotKey for this action
    597         return createExpressionPanel;
    598     }
    599
    600     private Action createShowColorPanelAction() {
    601         Action showColorPanel =
    602             new AbstractAction("", ChainsawIcons.ICON_PREFERENCES) {
    603                 public void actionPerformed(ActionEvent arg0) {
    604                     LogPanel logPanel = logui.getCurrentLogPanel();
    605
    606                     if (logPanel != null) {
    607                         logPanel.showColorPreferences();
    608                     }
    609                 }
    610             };
    611
    612         showColorPanel.putValue(
    613             Action.SHORT_DESCRIPTION, "Color settings...");
    614
    615         // TODO think of good mnemonics and HotKey for this action
    616         return showColorPanel;
    617     }
    618
    619     /**
    620      * @return
    621      */
    622     private Action createShowReceiversAction() {
    623         final Action action =
    624             new AbstractAction("Show Receivers") {
    625                 public void actionPerformed(ActionEvent arg0) {
    626                     logui.getApplicationPreferenceModel().setReceivers(
    627                         !logui.getApplicationPreferenceModel().isReceivers());
    628                 }
    629             };
    630
    631         action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_E);
    632         action.putValue(
    633             Action.SHORT_DESCRIPTION,
    634             "Shows the currently configured Log4j Receivers");
    635         action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("F6"));
    636         action.putValue(
    637             Action.SMALL_ICON, new ImageIcon(ChainsawIcons.ANIM_NET_CONNECT));
    638         toggleShowReceiversCheck.setAction(action);
    639
    640         return action;
    641     }
    642
    643     private Action createToggleDetailPaneAction() {
    644         Action action =
    645             new AbstractAction("Show Detail Pane") {
    646                 public void actionPerformed(ActionEvent evt) {
    647                     LogPanel logPanel = logui.getCurrentLogPanel();
    648
    649                     if (logPanel == null) {
    650                         return;
    651                     }
    652
    653                     logPanel.toggleDetailVisible();
    654                 }
    655             };
    656
    657         action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_D);
    658         action.putValue(
    659             Action.ACCELERATOR_KEY,
    660             KeyStroke.getKeyStroke(KeyEvent.VK_D, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
    661         action.putValue(Action.SHORT_DESCRIPTION, "Hides/Shows the Detail Pane");
    662         action.putValue(Action.SMALL_ICON, new ImageIcon(ChainsawIcons.INFO));
    663
    664         return action;
    665     }
    666
    667     private Action createToggleToolbarAction() {
    668         /**
    669          * -== Begin of Show/Hide toolbar action
    670          */
    671         final Action action =
    672             new AbstractAction("Show Toolbar") {
    673                 public void actionPerformed(ActionEvent e) {
    674                     logui.getApplicationPreferenceModel().setToolbar(
    675                         !logui.getApplicationPreferenceModel().isToolbar());
    676                 }
    677             };
    678
    679         action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_T);
    680
    681         return action;
    682     }
    683
    684     private void createToolbar() {
    685         Insets buttonMargins = new Insets(1, 1, 1, 1);
    686
    687         FileMenu menu = (FileMenu) menuBar.getMenu(0);
    688
    689         JButton fileOpenButton = new SmallButton(menu.getLog4JFileOpenAction());
    690         fileOpenButton.setMargin(buttonMargins);
    691
    692         JButton fileSaveButton = new SmallButton(menu.getFileSaveAction());
    693         fileSaveButton.setMargin(buttonMargins);
    694
    695         fileOpenButton.setText("");
    696         fileSaveButton.setText("");
    697
    698         toolbar.add(fileOpenButton);
    699         toolbar.add(fileSaveButton);
    700         toolbar.addSeparator();
    701
    702         pauseButton.setAction(pauseAction);
    703         pauseButton.setText("");
    704
    705         //		pauseButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("F12"),pauseAction.getValue(Action.NAME) );
    706         pauseButton.getActionMap().put(
    707             pauseAction.getValue(Action.NAME), pauseAction);
    708
    709         toggleCyclicButton.setAction(changeModelAction);
    710         toggleCyclicButton.setText(null);
    711
    712         detailPaneButton.setAction(toggleDetailPaneAction);
    713         detailPaneButton.setText(null);
    714         detailPaneButton.getActionMap().put(
    715             toggleDetailPaneAction.getValue(Action.NAME), toggleDetailPaneAction);
    716         detailPaneButton.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
    717             KeyStroke.getKeyStroke(KeyEvent.VK_D, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()),
    718             toggleDetailPaneAction.getValue(Action.NAME));
    719
    720         logTreePaneButton.setAction(toggleLogTreeAction);
    721         logTreePaneButton.getActionMap().put(
    722             toggleLogTreeAction.getValue(Action.NAME), toggleLogTreeAction);
    723         logTreePaneButton.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
    724             KeyStroke.getKeyStroke(KeyEvent.VK_T, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()),
    725             toggleLogTreeAction.getValue(Action.NAME));
    726         logTreePaneButton.setText(null);
    727
    728         scrollToBottomButton.setAction(toggleScrollToBottomAction);
    729         scrollToBottomButton.getActionMap().put(
    730             toggleScrollToBottomAction.getValue(Action.NAME), toggleScrollToBottomAction);
    731         scrollToBottomButton.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
    732             KeyStroke.getKeyStroke(KeyEvent.VK_B, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()),
    733             toggleScrollToBottomAction.getValue(Action.NAME));
    734         scrollToBottomButton.setText(null);
    735
    736         SmallButton prefsButton = new SmallButton(showPreferencesAction);
    737         SmallButton undockButton = new SmallButton(undockAction);
    738         undockButton.setText("");
    739
    740         toolbar.add(undockButton);
    741         toolbar.add(pauseButton);
    742         toolbar.add(toggleCyclicButton);
    743         toolbar.addSeparator();
    744         toolbar.add(detailPaneButton);
    745         toolbar.add(logTreePaneButton);
    746         toolbar.add(scrollToBottomButton);
    747         toolbar.add(prefsButton);
    748         toolbar.addSeparator();
    749
    750         toolbar.add(clearButton);
    751         clearButton.setAction(clearAction);
    752         clearButton.setText("");
    753         toolbar.addSeparator();
    754
    755         showReceiversButton.setText(null);
    756         toolbar.add(showReceiversButton);
    757
    758         toolbar.add(Box.createHorizontalGlue());
    759
    760         toolbar.setMargin(buttonMargins);
    761         toolbar.setFloatable(false);
    762     }
    763
    764     private Action createUndockAction() {
    765         Action action =
    766             new AbstractAction("Undock", ChainsawIcons.ICON_UNDOCK) {
    767                 public void actionPerformed(ActionEvent arg0) {
    768                     LogPanel logPanel = logui.getCurrentLogPanel();
    769
    770                     if (logPanel != null) {
    771                         logPanel.undock();
    772                     }
    773                 }
    774             };
    775
    776         action.putValue(
    777             Action.SHORT_DESCRIPTION,
    778             "Undocks the current Log panel into its own window");
    779
    780         //	TODO think of some mnemonics and HotKeys for this action
    781         return action;
    782     }
    783
    784     private void scanState() {
    785         toggleStatusBarCheck.setSelected(logui.isStatusBarVisible());
    786         toggleShowReceiversCheck.setSelected(
    787             logui.getApplicationPreferenceModel().isReceivers());
    788
    789         logTreePaneButton.setSelected(logui.isLogTreePanelVisible());
    790         LogPanel panel = logui.getCurrentLogPanel();
    791         if (panel != null) {
    792             scrollToBottomButton.setSelected(panel.isScrollToBottom());
    793             toggleDetailMenuItem.setSelected(panel.isDetailVisible());
    794         } else {
    795             scrollToBottomButton.setSelected(false);
    796             toggleDetailMenuItem.setSelected(false);
    797         }
    798         showReceiversButton.setSelected(
    799             logui.getApplicationPreferenceModel().isReceivers());
    800         menuShowWelcome.setSelected(logui.getTabbedPane().containsWelcomePanel());
    801
    802         /**
    803          * We get the currently selected LogPanel, and if null, deactivate some
    804          * actions
    805          */
    806         LogPanel logPanel = logui.getCurrentLogPanel();
    807
    808         boolean activateLogPanelActions = true;
    809
    810         if (logPanel == null) {
    811             activateLogPanelActions = false;
    812             activeTabMenu.setEnabled(false);
    813             toggleWelcomeVisibleAction.setEnabled(true);
    814             detailPaneButton.setSelected(false);
    815             toggleCyclicButton.setSelected(false);
    816         } else {
    817             activeTabMenu.setEnabled(true);
    818             fileMenu.getFileSaveAction().setEnabled(true);
    819             pauseButton.getModel().setSelected(logPanel.isPaused());
    820             toggleCyclicButton.setSelected(logPanel.isCyclic());
    821             logui.getStatusBar().setPaused(logPanel.isPaused(), logPanel.getIdentifier());
    822             toggleCyclicMenuItem.setSelected(logPanel.isCyclic());
    823             detailPaneButton.getModel().setSelected(logPanel.isDetailVisible());
    824             toggleLogTreeMenuItem.setSelected(logPanel.isLogTreeVisible());
    825             toggleScrollToBottomMenuItem.setSelected(logPanel.isScrollToBottom());
    826         }
    827
    828         for (Action logPanelSpecificAction : logPanelSpecificActions) {
    829             logPanelSpecificAction.setEnabled(activateLogPanelActions);
    830         }
    831
    832         String currentLookAndFeelName = UIManager.getLookAndFeel().getName();
    833
    834         for (Object lookAndFeelMenu : lookAndFeelMenus) {
    835             JRadioButtonMenuItem element = (JRadioButtonMenuItem) lookAndFeelMenu;
    836
    837             if (element.getText().equals(currentLookAndFeelName)) {
    838                 element.setSelected(true);
    839             } else {
    840                 element.setSelected(false);
    841             }
    842         }
    843     }
    844
    845     private Action getFindNextColorizedEventAction() {
    846         final Action action =
    847             new AbstractAction("Find next colorized event") {
    848                 public void actionPerformed(ActionEvent e) {
    849                     LogPanel p = logui.getCurrentLogPanel();
    850                     if (p != null) {
    851                         p.findNextColorizedEvent();
    852                     }
    853                 }
    854             };
    855         action.putValue(Action.SHORT_DESCRIPTION, "Find the next colorized event from the current location");
    856         action.putValue("enabled", Boolean.TRUE);
    857         action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_N);
    858         action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_N, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
    859
    860         return action;
    861     }
    862
    863     private Action getFindPreviousColorizedEventAction() {
    864         final Action action =
    865             new AbstractAction("Find previous colorized event") {
    866                 public void actionPerformed(ActionEvent e) {
    867                     LogPanel p = logui.getCurrentLogPanel();
    868
    869                     if (p != null) {
    870                         p.findPreviousColorizedEvent();
    871                     }
    872                 }
    873             };
    874         action.putValue(Action.SHORT_DESCRIPTION, "Find the next colorized event from the current location");
    875         action.putValue("enabled", Boolean.TRUE);
    876         action.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_P);
    877         action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_P, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
    878
    879         return action;
    880     }
    881
    882     private JPanel getCustomExpressionPanel() {
    883         final JPanel panel = new JPanel(new BorderLayout());
    884         panel.add(
    885             new JLabel("Enter expression for new tab:  "), BorderLayout.NORTH);
    886
    887         final JEditorPane entryField = new JEditorPane();
    888         entryField.setPreferredSize(new Dimension(350, 75));
    889         JTextComponentFormatter.applySystemFontAndSize(entryField);
    890         entryField.addKeyListener(
    891             new ExpressionRuleContext(new FilterModel(), entryField));
    892         panel.add(entryField, BorderLayout.CENTER);
    893
    894         JButton ok = new JButton(" OK ");
    895         JButton close = new JButton(" Close ");
    896         JPanel lowerPanel = new JPanel();
    897         lowerPanel.add(ok);
    898         lowerPanel.add(Box.createHorizontalStrut(7));
    899         lowerPanel.add(close);
    900         panel.add(lowerPanel, BorderLayout.SOUTH);
    901
    902         ok.addActionListener(
    903             new AbstractAction() {
    904                 public void actionPerformed(ActionEvent evt) {
    905                     logui.createCustomExpressionLogPanel(entryField.getText());
    906                     SwingUtilities.getAncestorOfClass(JDialog.class, panel).setVisible(
    907                         false);
    908                 }
    909             });
    910
    911         close.addActionListener(
    912             new AbstractAction() {
    913                 public void actionPerformed(ActionEvent evt) {
    914                     SwingUtilities.getAncestorOfClass(JDialog.class, panel).setVisible(
    915                         false);
    916                 }
    917             });
    918
    919         //String expression = JOptionPane.showInputDialog(logui, "Enter expression", "Create custom expression LogPanel", JOptionPane.PLAIN_MESSAGE);
    920         return panel;
    921     }
    922 }