KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > gjt > jclasslib > browser > config > classpath > ClasspathBrowser


1 /*
2     This library is free software; you can redistribute it and/or
3     modify it under the terms of the GNU General Public
4     License as published by the Free Software Foundation; either
5     version 2 of the license, or (at your option) any later version.
6 */

7
8 package org.gjt.jclasslib.browser.config.classpath;
9
10 import org.gjt.jclasslib.browser.BrowserMDIFrame;
11 import org.gjt.jclasslib.util.GUIHelper;
12 import org.gjt.jclasslib.util.ProgressDialog;
13
14 import javax.swing.*;
15 import javax.swing.event.TreeSelectionEvent JavaDoc;
16 import javax.swing.event.TreeSelectionListener JavaDoc;
17 import javax.swing.tree.DefaultTreeModel JavaDoc;
18 import javax.swing.tree.TreePath JavaDoc;
19 import java.awt.*;
20 import java.awt.event.*;
21
22 /**
23     Classpath browser that shows a tree of the contents of a
24     <tt>ClasspathComponent</tt>.
25
26     @author <a HREF="mailto:jclasslib@ej-technologies.com">Ingo Kegel</a>
27     @version $Revision: 1.1 $ $Date: 2003/08/18 08:10:15 $
28 */

29 public class ClasspathBrowser extends JDialog
30                               implements ActionListener, ClasspathChangeListener
31 {
32
33     private static final int DIALOG_WIDTH = 450;
34     private static final int DIALOG_HEIGHT = 450;
35
36     private BrowserMDIFrame frame;
37     private ClasspathComponent classpathComponent;
38
39     private JLabel lblTitle;
40     private JTree tree;
41     private JScrollPane scpTree;
42     private JButton btnSetup;
43     private JButton btnSync;
44     private JButton btnOk;
45     private JButton btnCancel;
46
47     private ProgressDialog progressDialog;
48     private boolean resetOnNextMerge;
49     private boolean needsMerge;
50
51     private String JavaDoc selectedClassName;
52
53     /**
54      * Constructor.
55      * @param frame the parent frame.
56      * @param classpathComponent the classpath component to display initially.
57      * @param title the disalog title.
58      * @param setupVisible if the <i>setup classpath</i> button should be visible.
59      */

60     public ClasspathBrowser(BrowserMDIFrame frame, ClasspathComponent classpathComponent, String JavaDoc title, boolean setupVisible) {
61         super(frame);
62         this.frame = frame;
63
64         setClasspathComponent(classpathComponent);
65         setupControls(title, setupVisible);
66         setupComponent();
67         setupEventHandlers();
68     }
69
70     public void actionPerformed(ActionEvent event) {
71         Object JavaDoc source = event.getSource();
72         if (source == btnCancel) {
73             doCancel();
74         } else if (source == btnOk) {
75             doOk();
76         } else if (source == btnSetup) {
77             doSetup();
78         } else if (source == btnSync) {
79             doSync(true);
80         }
81
82     }
83
84     public void classpathChanged(ClasspathChangeEvent event) {
85         needsMerge = true;
86         if (event.isRemoval()) {
87             resetOnNextMerge = true;
88         }
89     }
90
91     public void setVisible(boolean visible) {
92         if (visible) {
93             selectedClassName = null;
94         }
95         super.setVisible(visible);
96     }
97
98     /**
99      * Get the name of the selected class.
100      * @return the name
101      */

102     public String JavaDoc getSelectedClassName() {
103         return selectedClassName;
104     }
105
106     /**
107      * Set the new classpath component to be displayed by this dialog.
108      * The previous content will be cleared.
109      * @param classpathComponent the new classpath component.
110      */

111     public void setClasspathComponent(ClasspathComponent classpathComponent) {
112         if (this.classpathComponent != null) {
113             this.classpathComponent.removeClasspathChangeListener(this);
114         }
115         this.classpathComponent = classpathComponent;
116         if (classpathComponent != null) {
117             classpathComponent.addClasspathChangeListener(this);
118         }
119         resetOnNextMerge = true;
120         needsMerge = true;
121         clear();
122     }
123
124     /**
125      * Clear the current contents of the dialog. The tree will not be synchronized
126      * automatically on the next <tt>setVisible</tt>.
127      */

128     public void clear() {
129         if (tree != null) {
130             tree.setModel(new DefaultTreeModel JavaDoc(new ClassTreeNode()));
131         }
132     }
133
134     private void setupControls(String JavaDoc title, boolean setupVisible) {
135
136         lblTitle = new JLabel(title);
137         tree = new JTree(new ClassTreeNode());
138         tree.setRootVisible(false);
139         tree.setShowsRootHandles(true);
140         tree.putClientProperty("JTree.lineStyle", "Angled");
141         scpTree = new JScrollPane(tree);
142
143         btnSetup = new JButton("Setup classpath");
144         btnSetup.setVisible(setupVisible);
145         btnSync = new JButton("Synchronize");
146         btnOk = new JButton("Ok");
147         btnOk.setEnabled(false);
148         btnCancel = new JButton("Cancel");
149         btnOk.setPreferredSize(btnCancel.getPreferredSize());
150
151         progressDialog = new ProgressDialog(this, null, "Scanning classpath ...");
152
153     }
154
155     private void setupComponent() {
156
157         Container contentPane = getContentPane();
158         contentPane.setLayout(new GridBagLayout());
159         GridBagConstraints gc = new GridBagConstraints();
160         gc.gridx = 0;
161         gc.gridy = 0;
162         gc.insets = new Insets(5, 5, 0, 5);
163         gc.weightx = 1;
164         gc.anchor = GridBagConstraints.NORTHWEST;
165         contentPane.add(lblTitle, gc);
166         gc.gridy++;
167
168         gc.weighty = 1;
169         gc.insets.top = 0;
170         gc.fill = GridBagConstraints.BOTH;
171         contentPane.add(scpTree, gc);
172         gc.gridy++;
173         gc.fill = GridBagConstraints.HORIZONTAL;
174         gc.weighty = 0;
175         gc.insets.top = 3;
176         gc.insets.bottom = 5;
177         contentPane.add(createButtonBox(), gc);
178         getRootPane().setDefaultButton(btnOk);
179
180         setSize(DIALOG_WIDTH, DIALOG_HEIGHT);
181         setModal(true);
182         setTitle("Choose a class");
183         GUIHelper.centerOnParentWindow(this, getOwner());
184         setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
185
186     }
187
188     private Box createButtonBox() {
189
190         Box box = Box.createHorizontalBox();
191         box.add(btnSetup);
192         box.add(btnSync);
193         box.add(Box.createHorizontalGlue());
194         box.add(btnOk);
195         box.add(btnCancel);
196
197         return box;
198     }
199
200     private void setupEventHandlers() {
201
202         btnCancel.addActionListener(this);
203         btnOk.addActionListener(this);
204         btnSetup.addActionListener(this);
205         btnSync.addActionListener(this);
206
207         addWindowListener(new WindowAdapter() {
208             public void windowClosing(WindowEvent event) {
209                 doCancel();
210             }
211         });
212         KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
213         Object JavaDoc key = new Object JavaDoc();
214
215         JComponent contentPane = (JComponent)getContentPane();
216         contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(keyStroke, key);
217         contentPane.getActionMap().put(key, new AbstractAction() {
218             public void actionPerformed(ActionEvent event) {
219                 doCancel();
220             }
221         });
222
223         addComponentListener(new ComponentAdapter() {
224             public void componentShown(ComponentEvent event) {
225                 conditionalUpdate();
226             }
227         });
228
229         tree.addTreeSelectionListener(new TreeSelectionListener JavaDoc() {
230             public void valueChanged(TreeSelectionEvent JavaDoc event) {
231                 checkTreeSelection();
232             }
233         });
234
235         tree.addMouseListener(new MouseAdapter() {
236             public void mouseClicked(MouseEvent event) {
237                 if (event.getClickCount() == 2 && isValidDoubleClickPath(event)) {
238                     doOk();
239                 }
240             }
241         });
242
243     }
244
245     private void conditionalUpdate() {
246         if (needsMerge) {
247             doSync(resetOnNextMerge);
248         }
249     }
250
251     private boolean isValidDoubleClickPath(MouseEvent event) {
252
253         TreePath JavaDoc locationPath = tree.getPathForLocation(event.getX(), event.getY());
254         TreePath JavaDoc selectionPath = tree.getSelectionPath();
255         if (selectionPath == null || locationPath == null || !selectionPath.equals(locationPath)) {
256             return false;
257         }
258         ClassTreeNode lastPathComponent = (ClassTreeNode)selectionPath.getLastPathComponent();
259         return !lastPathComponent.isPackageNode();
260     }
261
262     private void checkTreeSelection() {
263
264         TreePath JavaDoc selectionPath = tree.getSelectionPath();
265         boolean enabled = false;
266         if (selectionPath != null) {
267             ClassTreeNode classTreeNode = (ClassTreeNode)selectionPath.getLastPathComponent();
268             enabled = !classTreeNode.isPackageNode();
269         }
270         btnOk.setEnabled(enabled);
271     }
272
273     private void doOk() {
274
275         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
276         TreePath JavaDoc selectionPath = tree.getSelectionPath();
277         for (int i = 1; i < selectionPath.getPathCount(); i++) {
278             if (buffer.length() > 0) {
279                 buffer.append('/');
280             }
281             buffer.append(selectionPath.getPathComponent(i).toString());
282         }
283         selectedClassName = buffer.toString();
284
285         setVisible(false);
286     }
287
288
289     private void doCancel() {
290         setVisible(false);
291     }
292
293     private void doSetup() {
294         frame.getActionSetupClasspath().actionPerformed(new ActionEvent(this, 0, null));
295         conditionalUpdate();
296     }
297
298     private void doSync(final boolean reset) {
299
300         final DefaultTreeModel JavaDoc model = reset ? new DefaultTreeModel JavaDoc(new ClassTreeNode()) : (DefaultTreeModel JavaDoc)tree.getModel();
301         Runnable JavaDoc mergeTask = new Runnable JavaDoc() {
302             public void run() {
303                 if (classpathComponent != null) {
304                     classpathComponent.mergeClassesIntoTree(model, reset);
305                 }
306             }
307         };
308
309         progressDialog.setRunnable(mergeTask);
310         progressDialog.setVisible(true);
311
312         if (reset) {
313             tree.setModel(model);
314         }
315         tree.expandPath(new TreePath JavaDoc(model.getRoot()));
316         resetOnNextMerge = false;
317         needsMerge = false;
318     }
319
320
321 }
322
Popular Tags