KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openide > loaders > TemplateWizard1


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.openide.loaders;
21
22 import java.awt.Component JavaDoc;
23 import java.util.LinkedList JavaDoc;
24 import java.util.ResourceBundle JavaDoc;
25 import javax.swing.JComponent JavaDoc;
26 import javax.swing.SwingUtilities JavaDoc;
27 import javax.swing.UIManager JavaDoc;
28 import javax.swing.border.Border JavaDoc;
29 import javax.swing.border.EtchedBorder JavaDoc;
30 import javax.swing.event.ChangeEvent JavaDoc;
31 import javax.swing.event.ChangeListener JavaDoc;
32 import javax.swing.tree.TreeSelectionModel JavaDoc;
33 import org.openide.awt.HtmlBrowser;
34 import org.openide.awt.Mnemonics;
35 import org.openide.explorer.ExplorerManager;
36 import org.openide.explorer.view.BeanTreeView;
37 import org.openide.explorer.view.NodeTreeModel;
38 import org.openide.explorer.view.Visualizer;
39 import org.openide.filesystems.FileObject;
40 import org.openide.filesystems.Repository;
41 import org.openide.nodes.Children;
42 import org.openide.nodes.FilterNode;
43 import org.openide.nodes.Node;
44 import org.openide.util.AsyncGUIJob;
45 import org.openide.util.NbBundle;
46 import org.openide.util.RequestProcessor;
47 import org.openide.util.Utilities;
48
49 /** Dialog that can be used in create from template.
50 *
51 * @author Jaroslav Tulach
52 */

53 final class TemplateWizard1 extends javax.swing.JPanel JavaDoc implements DataFilter,
54     ExplorerManager.Provider, java.beans.PropertyChangeListener JavaDoc, AsyncGUIJob {
55     /** See org.openide.WizardDescriptor.PROP_CONTENT_SELECTED_INDEX
56      */

57     private static final String JavaDoc PROP_CONTENT_SELECTED_INDEX = "WizardPanel_contentSelectedIndex"; // NOI18N
58
/** See org.openide.WizardDescriptor.PROP_CONTENT_DATA
59      */

60     private static final String JavaDoc PROP_CONTENT_DATA = "WizardPanel_contentData"; // NOI18N
61
/** listener to changes in the wizard */
62     private ChangeListener JavaDoc listener;
63     /** selected template */
64     private DataObject template;
65     /** templates root */
66     private DataFolder templatesRoot;
67     /** manager for templates tree view */
68     private ExplorerManager manager;
69     
70     /** Initialization data structure for passing data between
71      * asynchronous background initialization and UI update */

72     private static final class InitData {
73         HtmlBrowser browser;
74         String JavaDoc noDescMsg;
75         Border JavaDoc noDescBorder;
76     }; // end of InitData
77

78     /** holds init data for async initialization */
79     private InitData initData;
80     
81     /** Creates new form NewFromTemplatePanel */
82     public TemplateWizard1 () {
83         initComponents ();
84
85         treeView = new TemplatesTreeView();
86         treeView.setDefaultActionAllowed(false);
87         treeView.setPopupAllowed(false);
88         treeView.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
89         java.awt.GridBagConstraints JavaDoc gridBagConstraints1 = new java.awt.GridBagConstraints JavaDoc();
90         gridBagConstraints1.gridx = 0;
91         gridBagConstraints1.gridy = 1;
92         gridBagConstraints1.fill = java.awt.GridBagConstraints.BOTH;
93         gridBagConstraints1.insets = new java.awt.Insets JavaDoc(0, 0, 11, 0);
94         gridBagConstraints1.weightx = 1.0;
95         gridBagConstraints1.weighty = 1.0;
96         add(treeView, gridBagConstraints1);
97
98         ResourceBundle JavaDoc bundle = org.openide.util.NbBundle.getBundle(TemplateWizard1.class);
99         
100         setName (bundle.getString("LAB_TemplateChooserPanelName"));
101
102         putClientProperty(PROP_CONTENT_SELECTED_INDEX, 0);
103         putClientProperty(PROP_CONTENT_DATA, new String JavaDoc[] {getName(), "..."}); // NOI18N
104

105         // Fix of #19667 - those values will be retreived in addNotify
106
putClientProperty("LAB_SelectTemplateBorder", // NOI18N
107
bundle.getString("LAB_SelectTemplateBorder"));
108         putClientProperty("LAB_TemplateDescriptionBorder", // NOI18N
109
bundle.getString("LAB_TemplateDescriptionBorder"));
110         putClientProperty("ACSD_TemplatesTree", // NOI18N
111
bundle.getString("ACSD_TemplatesTree"));
112         putClientProperty("ACSD_TemplateWizard1", // NOI18N
113
bundle.getString("ACSD_TemplateWizard1"));
114         // bugfix #19667 end
115

116         updateRootNode (null);
117         
118         templatesLabel.setLabelFor(treeView);
119         
120         noBrowser.setText(bundle.getString("MSG_InitDescription"));
121         java.awt.CardLayout JavaDoc card = (java.awt.CardLayout JavaDoc)browserPanel.getLayout();
122         card.show (browserPanel, "noBrowser"); // NOI18N
123
// for asynchnonous lazy init of this component
124
Utilities.attachInitJob(this, this);
125     }
126
127     public void addNotify() {
128         // overriden to set the labels later than in constructor
129
// in order to fix #19667
130
Mnemonics.setLocalizedText(templatesLabel,
131                 (String JavaDoc)getClientProperty("LAB_SelectTemplateBorder") // NOI18N
132
);
133         Mnemonics.setLocalizedText(browserLabel,
134             (String JavaDoc)getClientProperty("LAB_TemplateDescriptionBorder") // NOI18N
135
);
136
137         treeView.getAccessibleContext().setAccessibleDescription(
138             (String JavaDoc)getClientProperty("ACSD_TemplatesTree") // NOI18N
139
);
140         getAccessibleContext().setAccessibleDescription(
141             (String JavaDoc)getClientProperty("ACSD_TemplateWizard1") // NOI18N
142
);
143         
144         super.addNotify();
145     }
146     
147     /** Explorer manager for templates tree view */
148     public ExplorerManager getExplorerManager() {
149         if (manager == null) {
150             manager = new ExplorerManager();
151             manager.addPropertyChangeListener(this);
152         }
153         return manager;
154     }
155
156     /** Forward focus to tree view. */
157     @SuppressWarnings JavaDoc("deprecation")
158     public boolean requestDefaultFocus() {
159         return treeView.requestDefaultFocus();
160     }
161
162     /** Preffered size */
163     public java.awt.Dimension JavaDoc getPreferredSize() {
164         return TemplateWizard.PREF_DIM;
165     }
166     
167     /** Updates the root of templates.
168      * @param root the root folder
169      */

170     private void updateRootNode (DataFolder root) {
171         if (root == null) {
172             FileObject fo = Repository.getDefault ().getDefaultFileSystem ().findResource ("/Templates"); // NOI18N
173
if (fo != null && fo.isFolder ())
174                 root = DataFolder.findFolder (fo);
175         }
176
177         if (root == null || root.equals(templatesRoot))
178             return;
179
180         templatesRoot = root;
181
182         Children ch = new DataShadowFilterChildren(root.getNodeDelegate());
183         getExplorerManager().setRootContext(new DataShadowFilterNode (root.getNodeDelegate(), ch, root.getNodeDelegate().getDisplayName ()));
184     }
185
186     private class DataShadowFilterChildren extends FilterNode.Children {
187         
188         public DataShadowFilterChildren (Node or) {
189             super (or);
190         }
191         
192         /** Creates nodes for nodes.
193          */

194         @Override JavaDoc
195         protected Node[] createNodes(Node key) {
196             Node n = key;
197             String JavaDoc nodeName = n.getDisplayName();
198             
199             DataObject obj = null;
200             DataShadow shadow = n.getCookie(DataShadow.class);
201             if (shadow != null) {
202                 // I need DataNode here to get localized name of the
203
// shadow, but without the ugly "(->)" at the end
204
DataNode dn = new DataNode(shadow, Children.LEAF);
205                 nodeName = dn.getDisplayName();
206                 obj = shadow.getOriginal();
207                 n = obj.getNodeDelegate();
208             }
209             
210             if (obj == null)
211                 obj = n.getCookie(DataObject.class);
212             
213             if (obj != null) {
214                 if (obj.isTemplate ()) {
215                     // on normal nodes stop recursion
216
return new Node[] { new DataShadowFilterNode (n, Children.LEAF, nodeName) };
217                 }
218             
219                 if (acceptDataObject (obj)) {
220                     // on folders use normal filtering
221
return new Node[] { new DataShadowFilterNode (n, new DataShadowFilterChildren (n), nodeName) };
222                 }
223             }
224             return new Node[] {};
225         }
226
227     }
228     
229
230     private static class DataShadowFilterNode extends FilterNode {
231         
232         private String JavaDoc name;
233         
234         public DataShadowFilterNode (Node or, org.openide.nodes.Children children, String JavaDoc name) {
235             super (or, children);
236             this.name = name;
237             disableDelegation(FilterNode.DELEGATE_SET_DISPLAY_NAME);
238         }
239         
240         public String JavaDoc getDisplayName() {
241             return name;
242         }
243         
244         // issue 29867, rename should be prohibited
245
public boolean canRename () {
246             return false;
247         }
248         
249     }
250     
251
252     /** Updates description to reflect the one associated with given object.
253     * @param obj object
254     */

255     private void updateDescription (DataObject obj) {
256         java.net.URL JavaDoc url = null;
257         if (obj != null) {
258             url = TemplateWizard.getDescription (obj);
259         }
260         java.awt.CardLayout JavaDoc card = (java.awt.CardLayout JavaDoc)browserPanel.getLayout();
261         if (url != null &&
262             getExplorerManager().getSelectedNodes().length != 0) {
263             if (browser != null) {
264                 browser.setURL(url);
265                 if (!browser.isVisible()) {
266                     card.show (browserPanel, "browser"); // NOI18N
267
}
268             }
269         } else {
270             card.show (browserPanel, "noBrowser"); // NOI18N
271
}
272     }
273     
274     /** This method is called from within the constructor to
275      * initialize the form.
276      * WARNING: Do NOT modify this code. The content of this method is
277      * always regenerated by the FormEditor.
278      */

279     private void initComponents() {//GEN-BEGIN:initComponents
280
java.awt.GridBagConstraints JavaDoc gridBagConstraints;
281
282         browserPanel = new javax.swing.JPanel JavaDoc();
283         noBrowser = new javax.swing.JLabel JavaDoc();
284         templatesLabel = new javax.swing.JLabel JavaDoc();
285         browserLabel = new javax.swing.JLabel JavaDoc();
286
287         setLayout(new java.awt.GridBagLayout JavaDoc());
288
289         setPreferredSize(new java.awt.Dimension JavaDoc(0, 0));
290         browserPanel.setLayout(new java.awt.CardLayout JavaDoc());
291
292         // same background as html browser to avoid flicking
293
noBrowser.setBackground(javax.swing.UIManager.getDefaults().getColor("EditorPane.background"));
294         noBrowser.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
295         // bigger minimum size then usual to behave well in card
296
// layout together with HtmlBrowser
297
noBrowser.setMinimumSize(new java.awt.Dimension JavaDoc(0, 25));
298         noBrowser.setOpaque(true);
299         browserPanel.add(noBrowser, "noBrowser");
300
301         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
302         gridBagConstraints.gridx = 0;
303         gridBagConstraints.gridy = 3;
304         gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
305         gridBagConstraints.weighty = 0.5;
306         add(browserPanel, gridBagConstraints);
307
308         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
309         gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
310         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 0, 5, 0);
311         add(templatesLabel, gridBagConstraints);
312
313         gridBagConstraints = new java.awt.GridBagConstraints JavaDoc();
314         gridBagConstraints.gridx = 0;
315         gridBagConstraints.gridy = 2;
316         gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
317         gridBagConstraints.insets = new java.awt.Insets JavaDoc(0, 0, 5, 0);
318         add(browserLabel, gridBagConstraints);
319
320     }//GEN-END:initComponents
321

322
323     private void nameFocusGained (java.awt.event.FocusEvent JavaDoc evt) {//GEN-FIRST:event_nameFocusGained
324
}//GEN-LAST:event_nameFocusGained
325
private void templatesTreeValueChanged (javax.swing.event.TreeSelectionEvent JavaDoc evt) {//GEN-FIRST:event_templatesTreeValueChanged
326
}//GEN-LAST:event_templatesTreeValueChanged
327

328     /** Handles explorer manager property changes. */
329     public void propertyChange(java.beans.PropertyChangeEvent JavaDoc evt) {
330         if (evt.getPropertyName() == ExplorerManager.PROP_SELECTED_NODES && listener != null) {
331             listener.stateChanged (new ChangeEvent JavaDoc (this));
332             
333             updateDescription (template);
334         }
335     }
336
337
338     private void packagesListValueChanged (javax.swing.event.ListSelectionEvent JavaDoc evt) {//GEN-FIRST:event_packagesListValueChanged
339
}//GEN-LAST:event_packagesListValueChanged
340

341
342     // Variables declaration - do not modify//GEN-BEGIN:variables
343
private javax.swing.JLabel JavaDoc browserLabel;
344     private javax.swing.JPanel JavaDoc browserPanel;
345     private javax.swing.JLabel JavaDoc noBrowser;
346     private javax.swing.JLabel JavaDoc templatesLabel;
347     // End of variables declaration//GEN-END:variables
348
private TemplatesTreeView treeView;
349     private HtmlBrowser browser;
350
351     /** Should the data object be displayed or not?
352     * @param obj the data object
353     * @return <CODE>true</CODE> if the object should be displayed,
354     * <CODE>false</CODE> otherwise
355     */

356     public boolean acceptDataObject(DataObject obj) {
357         if (obj instanceof DataFolder) {
358             Object JavaDoc o = obj.getPrimaryFile ().getAttribute ("simple"); // NOI18N
359
return o == null || Boolean.TRUE.equals (o);
360         } else {
361             return obj.isTemplate();
362         }
363     }
364
365     /** Prepares decription area with html browser inside.
366      * Executed in other then event dispatch thread.
367      */

368     public void construct() {
369         initData = new InitData();
370         initData.browser = new HtmlBrowser(false, false);
371         initData.browser.setName("browser");
372         initData.noDescMsg = NbBundle.getBundle(TemplateWizard1.class).
373                             getString("MSG_NoDescription");
374         initData.noDescBorder = new EtchedBorder JavaDoc();
375
376         // override the Swing default CSS to make the HTMLEditorKit use the
377
// same font as the rest of the UI
378

379         Component JavaDoc comp = initData.browser.getBrowserComponent();
380         if (! (comp instanceof javax.swing.JEditorPane JavaDoc))
381             return;
382
383         javax.swing.text.EditorKit JavaDoc kit = ((javax.swing.JEditorPane JavaDoc) comp).getEditorKitForContentType("text/html"); // NOI18N
384
if (! (kit instanceof javax.swing.text.html.HTMLEditorKit JavaDoc))
385             return;
386
387         javax.swing.text.html.HTMLEditorKit JavaDoc htmlkit = (javax.swing.text.html.HTMLEditorKit JavaDoc) kit;
388
389         // XXX the style sheet is shared by all HTMLEditorKits. We must
390
// detect if it has been tweaked by ourselves or someone else
391
// (template description for example) and avoid doing the same
392
// thing again
393

394         if (htmlkit.getStyleSheet().getStyleSheets() != null)
395             return;
396         
397         javax.swing.text.html.StyleSheet JavaDoc css = new javax.swing.text.html.StyleSheet JavaDoc();
398         java.awt.Font JavaDoc f = new javax.swing.JTextArea JavaDoc().getFont();
399         css.addRule(new StringBuffer JavaDoc("body { font-size: ").append(f.getSize()) // NOI18N
400
.append("; font-family: ").append(f.getName()).append("; }").toString()); // NOI18N
401
css.addStyleSheet(htmlkit.getStyleSheet());
402         htmlkit.setStyleSheet(css);
403     }
404
405     /** Fills description area using constructed data. Executed in event dispatch thread.
406      */

407     public void finished() {
408         browser = initData.browser;
409         browserLabel.setLabelFor(browser);
410         browser.getAccessibleContext().setAccessibleName(browserLabel.getText());
411         browserPanel.add(browser, "browser");
412         updateDescription(template);
413         // change loading text to no description text
414
// install same border as html browser have
415
noBrowser.setText(initData.noDescMsg);
416         noBrowser.setBorder(initData.noDescBorder);
417         // we don't need initData anymore, make gc'able
418
initData = null;
419     }
420     
421     /** Helper implementation of WizardDescription.Panel for TemplateWizard.Panel1.
422     * Provides the wizard panel with the current data--either
423     * the default data or already-modified settings, if the user used the previous and/or next buttons.
424     * This method can be called multiple times on one instance of <code>WizardDescriptor.Panel</code>.
425     * @param settings the object representing wizard panel state, as originally supplied to {@link WizardDescriptor#WizardDescriptor(WizardDescriptor.Iterator,Object)}
426     */

427     void implReadSettings (Object JavaDoc settings) {
428         TemplateWizard wizard = (TemplateWizard)settings;
429         wizard.setTitle(org.openide.util.NbBundle.getBundle(TemplateWizard.class).getString("CTL_TemplateTitle"));
430         updateRootNode (wizard.getTemplatesFolder ());
431
432         template = wizard.getTemplate ();
433         if (template != null && !template.isValid() ) {
434             template = null;
435         }
436
437         // now try to find out the path
438
// a bit ugly code to do that
439
DataObject obj = template;
440         DataObject stop = wizard.getTemplatesFolder ();
441         final LinkedList JavaDoc<String JavaDoc> names = new LinkedList JavaDoc<String JavaDoc>();
442         for (;;) {
443             if (obj == null) {
444                 // seems that the template is not one of templates
445
break;
446             }
447
448             if (obj == stop) {
449                 // the last object found
450
break;
451             }
452
453             String JavaDoc key = obj.getNodeDelegate().getName ();
454             names.addFirst(key);
455             obj = obj.getFolder();
456         }
457
458         RequestProcessor.getDefault ().post (new Runnable JavaDoc () {
459             private Node selection;
460             
461             public void run () {
462                 if (selection == null) {
463                     // go thru all the nodes and find
464
Node node = getExplorerManager().getRootContext();
465                     for (String JavaDoc name : names) {
466                         node = node.getChildren ().findChild (name);
467                         if (node == null) {
468                             // end it
469
node = getExplorerManager().getRootContext();
470                             break;
471                         }
472                     }
473                     
474                     selection = node;
475                     
476                     // execute the second pass
477
SwingUtilities.invokeLater (this);
478                 } else {
479                     // second pass, executed in AWT thread
480
try {
481                         getExplorerManager().setSelectedNodes(new Node[] {selection});
482                     } catch (java.beans.PropertyVetoException JavaDoc evt) {
483                         // ignore
484
}
485                 }
486             }
487         }, 300, Thread.MIN_PRIORITY);
488     }
489
490     /** Helper implementation of WizardDescription.Panel for TemplateWizard.Panel1.
491     * Provides the wizard panel with the opportunity to update the
492     * settings with its current customized state.
493     * Rather than updating its settings with every change in the GUI, it should collect them,
494     * and then only save them when requested to by this method.
495     * Also, the original settings passed to {@link #readSettings} should not be modified (mutated);
496     * rather, the (copy) passed in here should be mutated according to the collected changes.
497     * This method can be called multiple times on one instance of <code>WizardDescriptor.Panel</code>.
498     * @param settings the object representing a settings of the wizard
499     */

500     void implStoreSettings (Object JavaDoc settings) {
501         if (template != null) {
502             TemplateWizard wizard = (TemplateWizard)settings;
503             if (wizard.getTemplate() != template) {
504                 // if template has changed then set target step names and index to default
505
Component JavaDoc c = wizard.targetChooser().getComponent();
506                 if (c instanceof JComponent JavaDoc) {
507                     ((JComponent JavaDoc)c).putClientProperty(PROP_CONTENT_DATA, new String JavaDoc[] { c.getName() });
508                     ((JComponent JavaDoc)c).putClientProperty(PROP_CONTENT_SELECTED_INDEX, new Integer JavaDoc(0));
509                 }
510             } else {
511                 // bugfix #27939, if template isn't changed and PROP_CONTENT_DATA no set => set it
512
Component JavaDoc c = wizard.targetChooser().getComponent();
513                 if (c instanceof JComponent JavaDoc) {
514                     if (((JComponent JavaDoc)c).getClientProperty (PROP_CONTENT_DATA) == null) {
515                         ((JComponent JavaDoc)c).putClientProperty(PROP_CONTENT_DATA, new String JavaDoc[] { c.getName() });
516                         ((JComponent JavaDoc)c).putClientProperty(PROP_CONTENT_SELECTED_INDEX, new Integer JavaDoc(0));
517                     }
518                 }
519             }
520             wizard.setTemplateImpl (template, false);
521         }
522     }
523
524     /** Helper implementation of WizardDescription.Panel for TemplateWizard.Panel1.
525     * Test whether the panel is finished and it is safe to proceed to the next one.
526     * If the panel is valid, the "Next" (or "Finish") button will be enabled.
527     * @return <code>true</code> if the user has entered satisfactory information
528     */

529     boolean implIsValid () {
530         boolean enable = false;
531         Node[] n = getExplorerManager().getSelectedNodes();
532         if (n.length == 1) {
533             template = n[0].getCookie(DataObject.class);
534             enable = template != null && template.isTemplate();
535         }
536         return enable;
537     }
538
539     /** Add a listener to changes of the panel's validity.
540     * @param l the listener to add
541     * @see #isValid
542     */

543     void addChangeListener (ChangeListener JavaDoc l) {
544         if (listener != null) throw new IllegalStateException JavaDoc ();
545         listener = l;
546     }
547
548     /** Remove a listener to changes of the panel's validity.
549     * @param l the listener to remove
550     */

551     void removeChangeListener (ChangeListener JavaDoc l) {
552         listener = null;
553     }
554
555     
556     /** Model for displaying only objects till template.
557     */

558     private static final class TemplatesModel extends NodeTreeModel {
559         TemplatesModel() {}
560         
561         public int getChildCount (Object JavaDoc o) {
562             Node n = Visualizer.findNode(o);
563             DataObject obj = n.getCookie(DataObject.class);
564
565             return obj == null || obj.isTemplate () ? 0 : super.getChildCount (o);
566         }
567
568         public boolean isLeaf (Object JavaDoc o) {
569             Node n = Visualizer.findNode(o);
570             DataObject obj = n.getCookie(DataObject.class);
571
572             return obj == null || obj.isTemplate ();
573         }
574     }
575
576     /** Specialized tree view for templates, non editable and with proper
577      * border */

578     private static final class TemplatesTreeView extends BeanTreeView {
579         TemplatesTreeView() {
580             tree.setEditable(false);
581             // install proper border
582
setBorder((Border JavaDoc)UIManager.get("Nb.ScrollPane.border")); // NOI18N
583
}
584         
585         protected NodeTreeModel createModel() {
586             return new TemplatesModel();
587         }
588     }
589 }
590
Popular Tags