KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jivesoftware > smackx > debugger > EnhancedDebuggerWindow


1 /**
2  * $RCSfile$
3  * $Revision: 2457 $
4  * $Date: 2005-02-07 18:37:23 -0300 (Mon, 07 Feb 2005) $
5  *
6  * Copyright 2003-2004 Jive Software.
7  *
8  * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */

20
21 package org.jivesoftware.smackx.debugger;
22
23 import java.awt.*;
24 import java.awt.event.*;
25 import java.net.*;
26 import java.util.*;
27
28 import javax.swing.*;
29
30 import org.jivesoftware.smack.SmackConfiguration;
31 import org.jivesoftware.smack.provider.ProviderManager;
32
33 /**
34  * The EnhancedDebuggerWindow is the main debug window that will show all the EnhancedDebuggers.
35  * For each connection to debug there will be an EnhancedDebugger that will be shown in the
36  * EnhancedDebuggerWindow.<p>
37  *
38  * This class also provides information about Smack like for example the Smack version and the
39  * installed providers.
40  *
41  * @author Gaston Dombiak
42  */

43 class EnhancedDebuggerWindow {
44
45     private static EnhancedDebuggerWindow instance;
46
47     private static ImageIcon connectionCreatedIcon;
48     private static ImageIcon connectionActiveIcon;
49     private static ImageIcon connectionClosedIcon;
50     private static ImageIcon connectionClosedOnErrorIcon;
51     
52     {
53         URL url;
54         
55         url =
56             Thread.currentThread().getContextClassLoader().getResource(
57                 "images/trafficlight_off.png");
58         if (url != null) {
59             connectionCreatedIcon = new ImageIcon(url);
60         }
61         url =
62             Thread.currentThread().getContextClassLoader().getResource(
63                 "images/trafficlight_green.png");
64         if (url != null) {
65             connectionActiveIcon = new ImageIcon(url);
66         }
67         url =
68             Thread.currentThread().getContextClassLoader().getResource(
69                 "images/trafficlight_red.png");
70         if (url != null) {
71             connectionClosedIcon = new ImageIcon(url);
72         }
73         url = Thread.currentThread().getContextClassLoader().getResource("images/warning.png");
74         if (url != null) {
75             connectionClosedOnErrorIcon = new ImageIcon(url);
76         }
77
78     }
79
80     private JFrame frame = null;
81     private JTabbedPane tabbedPane = null;
82     private java.util.List JavaDoc debuggers = new ArrayList();
83
84     private EnhancedDebuggerWindow() {
85     }
86
87     /**
88      * Returns the unique EnhancedDebuggerWindow instance available in the system.
89      *
90      * @return the unique EnhancedDebuggerWindow instance
91      */

92     private static EnhancedDebuggerWindow getInstance() {
93         if (instance == null) {
94             instance = new EnhancedDebuggerWindow();
95         }
96         return instance;
97     }
98
99     /**
100      * Adds the new specified debugger to the list of debuggers to show in the main window.
101      *
102      * @param debugger the new debugger to show in the debug window
103      */

104     synchronized static void addDebugger(EnhancedDebugger debugger) {
105         getInstance().showNewDebugger(debugger);
106     }
107
108     /**
109      * Shows the new debugger in the debug window.
110      *
111      * @param debugger the new debugger to show
112      */

113     private void showNewDebugger(EnhancedDebugger debugger) {
114         if (frame == null) {
115             createDebug();
116         }
117         debugger.tabbedPane.setName("Connection_" + tabbedPane.getComponentCount());
118         tabbedPane.add(debugger.tabbedPane, tabbedPane.getComponentCount() - 1);
119         tabbedPane.setIconAt(tabbedPane.indexOfComponent(debugger.tabbedPane), connectionCreatedIcon);
120         frame.setTitle(
121             "Smack Debug Window -- Total connections: " + (tabbedPane.getComponentCount() - 1));
122         // Keep the added debugger for later access
123
debuggers.add(debugger);
124     }
125
126     /**
127      * Notification that a user has logged in to the server. A new title will be set
128      * to the tab of the given debugger.
129      *
130      * @param debugger the debugger whose connection logged in to the server
131      * @param user the user@host/resource that has just logged in
132      */

133     synchronized static void userHasLogged(EnhancedDebugger debugger, String JavaDoc user) {
134         int index = getInstance().tabbedPane.indexOfComponent(debugger.tabbedPane);
135         getInstance().tabbedPane.setTitleAt(
136             index,
137             user);
138         getInstance().tabbedPane.setIconAt(
139             index,
140             connectionActiveIcon);
141     }
142
143     /**
144      * Notification that the connection was properly closed.
145      *
146      * @param debugger the debugger whose connection was properly closed.
147      */

148     synchronized static void connectionClosed(EnhancedDebugger debugger) {
149         getInstance().tabbedPane.setIconAt(
150             getInstance().tabbedPane.indexOfComponent(debugger.tabbedPane),
151             connectionClosedIcon);
152     }
153
154     /**
155      * Notification that the connection was closed due to an exception.
156      *
157      * @param debugger the debugger whose connection was closed due to an exception.
158      * @param e the exception.
159      */

160     synchronized static void connectionClosedOnError(EnhancedDebugger debugger, Exception JavaDoc e) {
161         int index = getInstance().tabbedPane.indexOfComponent(debugger.tabbedPane);
162         getInstance().tabbedPane.setToolTipTextAt(
163             index,
164             "Connection closed due to the exception: " + e.getMessage());
165         getInstance().tabbedPane.setIconAt(
166             index,
167             connectionClosedOnErrorIcon);
168     }
169
170     /**
171      * Creates the main debug window that provides information about Smack and also shows
172      * a tab panel for each connection that is being debugged.
173      */

174     private void createDebug() {
175
176         frame = new JFrame("Smack Debug Window");
177
178         // Add listener for window closing event
179
frame.addWindowListener(new WindowAdapter() {
180             public void windowClosing(WindowEvent evt) {
181                 rootWindowClosing(evt);
182             }
183         });
184
185         // We'll arrange the UI into tabs. The last tab contains Smack's information.
186
// All the connection debugger tabs will be shown before the Smack info tab.
187
tabbedPane = new JTabbedPane();
188
189         // Create the Smack info panel
190
JPanel informationPanel = new JPanel();
191         informationPanel.setLayout(new BoxLayout(informationPanel, BoxLayout.Y_AXIS));
192
193         // Add the Smack version label
194
JPanel versionPanel = new JPanel();
195         versionPanel.setLayout(new BoxLayout(versionPanel, BoxLayout.X_AXIS));
196         versionPanel.setMaximumSize(new Dimension(2000, 31));
197         versionPanel.add(new JLabel(" Smack version: "));
198         JFormattedTextField field = new JFormattedTextField(SmackConfiguration.getVersion());
199         field.setEditable(false);
200         field.setBorder(null);
201         versionPanel.add(field);
202         informationPanel.add(versionPanel);
203
204         // Add the list of installed IQ Providers
205
JPanel iqProvidersPanel = new JPanel();
206         iqProvidersPanel.setLayout(new GridLayout(1, 1));
207         iqProvidersPanel.setBorder(BorderFactory.createTitledBorder("Installed IQ Providers"));
208         Vector providers = new Vector();
209         for (Iterator it = ProviderManager.getIQProviders(); it.hasNext();) {
210             Object JavaDoc provider = it.next();
211             if (provider.getClass() == Class JavaDoc.class) {
212                 providers.add(((Class JavaDoc) provider).getName());
213             }
214             else {
215                 providers.add(provider.getClass().getName());
216             }
217         }
218         // Sort the collection of providers
219
Collections.sort(providers);
220         JList list = new JList(providers);
221         iqProvidersPanel.add(new JScrollPane(list));
222         informationPanel.add(iqProvidersPanel);
223
224         // Add the list of installed Extension Providers
225
JPanel extensionProvidersPanel = new JPanel();
226         extensionProvidersPanel.setLayout(new GridLayout(1, 1));
227         extensionProvidersPanel.setBorder(BorderFactory.createTitledBorder("Installed Extension Providers"));
228         providers = new Vector();
229         for (Iterator it = ProviderManager.getExtensionProviders(); it.hasNext();) {
230             Object JavaDoc provider = it.next();
231             if (provider.getClass() == Class JavaDoc.class) {
232                 providers.add(((Class JavaDoc) provider).getName());
233             }
234             else {
235                 providers.add(provider.getClass().getName());
236             }
237         }
238         // Sort the collection of providers
239
Collections.sort(providers);
240         list = new JList(providers);
241         extensionProvidersPanel.add(new JScrollPane(list));
242         informationPanel.add(extensionProvidersPanel);
243
244         tabbedPane.add("Smack Info", informationPanel);
245
246         // Add pop-up menu.
247
JPopupMenu menu = new JPopupMenu();
248         // Add a menu item that allows to close the current selected tab
249
JMenuItem menuItem = new JMenuItem("Close");
250         menuItem.addActionListener(new ActionListener() {
251             public void actionPerformed(ActionEvent e) {
252                 // Remove the selected tab pane if it's not the Smack info pane
253
if (tabbedPane.getSelectedIndex() < tabbedPane.getComponentCount() - 1) {
254                     int index = tabbedPane.getSelectedIndex();
255                     // Notify to the debugger to stop debugging
256
EnhancedDebugger debugger = (EnhancedDebugger)debuggers.get(index);
257                     debugger.cancel();
258                     // Remove the debugger from the root window
259
tabbedPane.remove(debugger.tabbedPane);
260                     debuggers.remove(debugger);
261                     // Update the root window title
262
frame.setTitle(
263                         "Smack Debug Window -- Total connections: "
264                             + (tabbedPane.getComponentCount() - 1));
265                 }
266             }
267         });
268         menu.add(menuItem);
269         // Add a menu item that allows to close all the tabs that have their connections closed
270
menuItem = new JMenuItem("Close All Not Active");
271         menuItem.addActionListener(new ActionListener() {
272             public void actionPerformed(ActionEvent e) {
273                 ArrayList debuggersToRemove = new ArrayList();
274                 // Remove all the debuggers of which their connections are no longer valid
275
for (int index=0; index < tabbedPane.getComponentCount()-1; index++) {
276                     EnhancedDebugger debugger = (EnhancedDebugger)debuggers.get(index);
277                     if (!debugger.isConnectionActive()) {
278                         // Notify to the debugger to stop debugging
279
debugger.cancel();
280                         debuggersToRemove.add(debugger);
281                     }
282                 }
283                 for (Iterator it=debuggersToRemove.iterator(); it.hasNext();) {
284                     EnhancedDebugger debugger = (EnhancedDebugger)it.next();
285                     // Remove the debugger from the root window
286
tabbedPane.remove(debugger.tabbedPane);
287                     debuggers.remove(debugger);
288                 }
289                 // Update the root window title
290
frame.setTitle(
291                     "Smack Debug Window -- Total connections: "
292                         + (tabbedPane.getComponentCount() - 1));
293             }
294         });
295         menu.add(menuItem);
296         // Add listener to the text area so the popup menu can come up.
297
tabbedPane.addMouseListener(new PopupListener(menu));
298
299         frame.getContentPane().add(tabbedPane);
300
301         frame.setSize(650, 400);
302         frame.setVisible(true);
303
304     }
305
306     /**
307      * Notification that the root window is closing. Stop listening for received and
308      * transmitted packets in all the debugged connections.
309      *
310      * @param evt the event that indicates that the root window is closing
311      */

312     public void rootWindowClosing(WindowEvent evt) {
313         // Notify to all the debuggers to stop debugging
314
for (Iterator it = debuggers.iterator(); it.hasNext();) {
315             EnhancedDebugger debugger = (EnhancedDebugger)it.next();
316             debugger.cancel();
317         }
318         // Release any reference to the debuggers
319
debuggers.removeAll(debuggers);
320         // Release the default instance
321
instance = null;
322     }
323
324     /**
325      * Listens for debug window popup dialog events.
326      */

327     private class PopupListener extends MouseAdapter {
328         JPopupMenu popup;
329
330         PopupListener(JPopupMenu popupMenu) {
331             popup = popupMenu;
332         }
333
334         public void mousePressed(MouseEvent e) {
335             maybeShowPopup(e);
336         }
337
338         public void mouseReleased(MouseEvent e) {
339             maybeShowPopup(e);
340         }
341
342         private void maybeShowPopup(MouseEvent e) {
343             if (e.isPopupTrigger()) {
344                 popup.show(e.getComponent(), e.getX(), e.getY());
345             }
346         }
347     }
348 }
349
Popular Tags