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  /*
    19   * @author Paul Smith &lt;psmith@apache.org&gt;
    20   *
    21   */
    22  package org.apache.log4j.chainsaw;
    23
    24  import com.thoughtworks.xstream.XStream;
    25  import com.thoughtworks.xstream.io.xml.DomDriver;
    26  import org.apache.log4j.chainsaw.prefs.LoadSettingsEvent;
    27  import org.apache.log4j.chainsaw.prefs.SaveSettingsEvent;
    28  import org.apache.log4j.chainsaw.prefs.SettingsListener;
    29  import org.apache.log4j.chainsaw.prefs.SettingsManager;
    30
    31  import javax.swing.*;
    32  import java.awt.*;
    33  import java.io.File;
    34  import java.io.FileReader;
    35  import java.io.FileWriter;
    36
    37
    38  /**
    39   * The only reason this class is needed is because
    40   * of a stupid 'issue' with the JTabbedPane.
    41   * <p>
    42   * If the currently selected tab is the first tab,
    43   * and we insert a new tab at the front, then as
    44   * far as the JTabbedPane is concerned, NO STATE has
    45   * changed, as the currently selected tab index is still
    46   * the same (even though the TAB is different - go figure)
    47   * and therefore no ChangeEvent is generated and sent
    48   * to listeners.  Thanks very much Sun!
    49   * <p>
    50   * For more information on the issue:
    51   * http://developer.java.sun.com/developer/bugParade/bugs/4253819.html
    52   *
    53   * @author Paul Smith &lt;psmith@apache.org&gt;
    54   * @author Scott Deboy &lt;sdeboy@apache.org&gt;
    55   */
    56
    57  class ChainsawTabbedPane extends JTabbedPane implements SettingsListener {
    58      public SavableTabSetting tabSetting;
    59      public static final String WELCOME_TAB = "Welcome";
    60      public static final String ZEROCONF = "Zeroconf";
    61
    62      /**
    63       * Create the tabbed pane.
    64       */
    65      public ChainsawTabbedPane() {
    66          super();
    67      }
    68
    69      /**
    70       * Returns true if this TabbedPane has an instance of the WelcomePanel
    71       * in it
    72       *
    73       * @return true/false
    74       */
    75      boolean containsWelcomePanel() {
    76          return indexOfTab("Welcome") > -1;
    77      }
    78
    79      /**
    80       * Our custom implementation of inserting a new tab,
    81       * this method ALWAYS inserts it at the front because
    82       * we get an ArrayIndexOutOfBoundsException otherwise
    83       * under some JDK implementations.
    84       * <p>
    85       * This method also causes a fireStateChange() to be
    86       * called so that listeners get notified of the event.
    87       * See the class level comments for the reason why...
    88       *
    89       * @param name
    90       * @param component
    91       */
    92      public void addANewTab(String name, JComponent component, Icon icon) {
    93          super.insertTab(name, icon, component, null, getTabCount());
    94
    95          super.fireStateChanged();
    96          if (!"chainsaw-log".equals(name)) {
    97              EventQueue.invokeLater(() -> setSelectedTab(getTabCount() - 1));
    98          }
    99      }
    100
    101     public void setSelectedTab(int index) {
    102         if (getTabCount() >= index) {
    103             setSelectedIndex(index);
    104         }
    105
    106         getSelectedComponent().setVisible(true);
    107         getSelectedComponent().validate();
    108         super.fireStateChanged();
    109     }
    110
    111     public void addANewTab(
    112         String name, JComponent component, Icon icon, String tooltip) {
    113         super.insertTab(name, icon, component, tooltip, getTabCount());
    114         super.fireStateChanged();
    115     }
    116
    117     public void remove(Component component) {
    118         super.remove(component);
    119         super.fireStateChanged();
    120     }
    121
    122     /**
    123      * Saves the state of the currently active tabs to an XML file.
    124      * Only considers the Welcome, Drag and Drop and chainsaw-log
    125      * panels as they are the panel which are always running. Saves
    126      * whether they are hidden or not....
    127      */
    128
    129     public void saveSettings(SaveSettingsEvent event) {
    130         File file = new File(SettingsManager.getInstance().getSettingsDirectory(), "tab-settings.xml");
    131         XStream stream = new XStream(new DomDriver());
    132         try {
    133             FileWriter writer = new FileWriter(file);
    134             int count = super.getTabCount();
    135             String title;
    136             SavableTabSetting setting = new SavableTabSetting();
    137             for (int i = 0; i < count; i++) {
    138                 title = super.getTitleAt(i);
    139                 switch (title) {
    140                     case WELCOME_TAB:
    141                         setting.setWelcome(true);
    142                         break;
    143                     case "chainsaw-log":
    144                         setting.setChainsawLog(true);
    145                         break;
    146                     case ZEROCONF:
    147                         setting.setZeroconf(true);
    148                         break;
    149                 }
    150             }
    151
    152             stream.toXML(setting, writer);
    153             writer.close();
    154
    155         } catch (Exception e) {
    156             file.delete();
    157             e.printStackTrace();
    158         }
    159     }
    160
    161     /**
    162      * Loads the saved tab setting by reading the XML file.
    163      * If the file doesn't exist, all three panels should be
    164      * shown as the default setting....
    165      */
    166
    167     public void loadSettings(LoadSettingsEvent event) {
    168         File file = new File(SettingsManager.getInstance().getSettingsDirectory(), "tab-settings.xml");
    169         XStream stream = new XStream(new DomDriver());
    170         try {
    171             if (file.exists()) {
    172                 FileReader reader = new FileReader(file);
    173                 tabSetting = (SavableTabSetting) stream.fromXML(reader);
    174                 reader.close();
    175             } else {
    176                 tabSetting = new SavableTabSetting();
    177                 tabSetting.setWelcome(true);
    178                 tabSetting.setChainsawLog(true);
    179                 tabSetting.setZeroconf(true);
    180             }
    181         } catch (Exception e) {
    182             e.printStackTrace();
    183             file.delete();
    184         }
    185     }
    186 }