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