alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.openide.loaders;

import java.util.*;

import javax.swing.tree.TreeSelectionModel;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import javax.swing.SwingUtilities;
import javax.swing.JComponent;
import java.awt.Component;
import java.awt.Graphics;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
import javax.swing.plaf.basic.BasicBorders;

import org.openide.awt.HtmlBrowser;
import org.openide.loaders.*;
import org.openide.nodes.*;
import org.openide.explorer.view.*;
import org.openide.util.RequestProcessor;
import org.openide.explorer.ExplorerManager;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.Repository;
import org.openide.util.AsyncGUIJob;
import org.openide.util.NbBundle;
import org.openide.util.Utilities;

/** Dialog that can be used in create from template.
*
* @author  Jaroslav Tulach
*/
final class TemplateWizard1 extends javax.swing.JPanel implements DataFilter,
    ExplorerManager.Provider, java.beans.PropertyChangeListener, AsyncGUIJob {
    /** See org.openide.WizardDescriptor.PROP_CONTENT_SELECTED_INDEX
     */
    private static final String PROP_CONTENT_SELECTED_INDEX = "WizardPanel_contentSelectedIndex"; // NOI18N
    /** See org.openide.WizardDescriptor.PROP_CONTENT_DATA
     */
    private static final String PROP_CONTENT_DATA = "WizardPanel_contentData"; // NOI18N
    /** listener to changes in the wizard */
    private ChangeListener listener;
    /** selected template */
    private DataObject template;
    /** templates root */
    private DataFolder templatesRoot;
    /** manager for templates tree view */
    private ExplorerManager manager;
    
    /** Initialization data structure for passing data between
     * asynchronous background initialization and UI update */
    private static final class InitData {
        HtmlBrowser browser;
        String noDescMsg;
        Border noDescBorder;
    }; // end of InitData
    
    /** holds init data for async initialization */
    private InitData initData;
    
    /** Creates new form NewFromTemplatePanel */
    public TemplateWizard1 () {
        initComponents ();

        treeView = new TemplatesTreeView();
        treeView.setDefaultActionAllowed(false);
        treeView.setPopupAllowed(false);
        treeView.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        java.awt.GridBagConstraints gridBagConstraints1 = new java.awt.GridBagConstraints();
        gridBagConstraints1.gridx = 0;
        gridBagConstraints1.gridy = 1;
        gridBagConstraints1.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints1.insets = new java.awt.Insets(0, 0, 11, 0);
        gridBagConstraints1.weightx = 1.0;
        gridBagConstraints1.weighty = 1.0;
        add(treeView, gridBagConstraints1);

        ResourceBundle bundle = org.openide.util.NbBundle.getBundle(TemplateWizard1.class);
        
        setName (bundle.getString("LAB_TemplateChooserPanelName"));

        putClientProperty(PROP_CONTENT_SELECTED_INDEX, new Integer(0));
        putClientProperty(PROP_CONTENT_DATA, new String[] {getName(), "..."}); // NOI18N
        
        // Fix of #19667 - those values will be retreived in addNotify
        putClientProperty("LAB_SelectTemplateBorder", // NOI18N
            bundle.getString("LAB_SelectTemplateBorder")); 
        putClientProperty("LAB_SelectTemplateBorder_Mnemonic", // NOI18N
            bundle.getString("LAB_SelectTemplateBorder_Mnemonic"));
        putClientProperty("LAB_TemplateDescriptionBorder", // NOI18N
            bundle.getString("LAB_TemplateDescriptionBorder"));
        putClientProperty("LAB_TemplateDescriptionBorder_Mnemonic", // NOI18N
            bundle.getString("LAB_TemplateDescriptionBorder_Mnemonic"));
        putClientProperty("ACSD_TemplatesTree", // NOI18N
            bundle.getString("ACSD_TemplatesTree"));
        putClientProperty("ACSD_TemplateWizard1", // NOI18N
            bundle.getString("ACSD_TemplateWizard1"));
        // bugfix #19667 end
        
        updateRootNode (null);
        
        templatesLabel.setLabelFor(treeView);
        
        noBrowser.setText(bundle.getString("MSG_InitDescription"));
        java.awt.CardLayout card = (java.awt.CardLayout)browserPanel.getLayout();
        card.show (browserPanel, "noBrowser"); // NOI18N
        // for asynchnonous lazy init of this component
        Utilities.attachInitJob(this, this);
    }

    public void addNotify() {
        // overriden to set the labels later than in constructor
        // in order to fix #19667
        templatesLabel.setText(
            (String)getClientProperty("LAB_SelectTemplateBorder") // NOI18N
        );
        templatesLabel.setDisplayedMnemonic(
            ((String)getClientProperty("LAB_SelectTemplateBorder_Mnemonic")).charAt(0) // NOI18N
        );
        browserLabel.setText(
            (String)getClientProperty("LAB_TemplateDescriptionBorder") // NOI18N
        );
        browserLabel.setDisplayedMnemonic(
            ((String)getClientProperty("LAB_TemplateDescriptionBorder_Mnemonic")).charAt(0)
        );

        treeView.getAccessibleContext().setAccessibleDescription(
            (String)getClientProperty("ACSD_TemplatesTree") // NOI18N
        );
        getAccessibleContext().setAccessibleDescription(
            (String)getClientProperty("ACSD_TemplateWizard1") // NOI18N
        );
        
        super.addNotify();
    }
    
    /** Explorer manager for templates tree view */
    public ExplorerManager getExplorerManager() {
        if (manager == null) {
            manager = new ExplorerManager();
            manager.addPropertyChangeListener(this);
        }
        return manager;
    }

    /** Forward focus to tree view. */
    public boolean requestDefaultFocus() {
        return treeView.requestDefaultFocus();
    }

    /** Preffered size */
    public java.awt.Dimension getPreferredSize() {
        return TemplateWizard.PREF_DIM;
    }
    
    /** Updates the root of templates.
     * @param root the root folder
     */
    private void updateRootNode (DataFolder root) {
        if (root == null) {
            FileObject fo = Repository.getDefault ().getDefaultFileSystem ().findResource ("/Templates"); // NOI18N
            if (fo != null && fo.isFolder ())
                root = DataFolder.findFolder (fo);
        }

        if (root.equals(templatesRoot))
            return;

        templatesRoot = root;

        Children ch = new DataShadowFilterChildren(root.getNodeDelegate());
        getExplorerManager().setRootContext(new DataShadowFilterNode (root.getNodeDelegate(), ch, root.getNodeDelegate().getDisplayName ()));
    }

    private class DataShadowFilterChildren extends FilterNode.Children {
        
        public DataShadowFilterChildren (Node or) {
            super (or);
        }
        
        /** Creates nodes for nodes.
         */
        protected Node[] createNodes (Object key) {
            Node n = (Node)key;
            String nodeName = n.getDisplayName();
            
            DataObject obj = null;
            DataShadow shadow = (DataShadow)n.getCookie (DataShadow.class);
            if (shadow != null) {
                // I need DataNode here to get localized name of the
                // shadow, but without the ugly "(->)" at the end
                DataNode dn = new DataNode(shadow, Children.LEAF);
                nodeName = dn.getDisplayName();
                obj = shadow.getOriginal();
                n = obj.getNodeDelegate();
            }
            
            if (obj == null)
                obj = (DataObject)n.getCookie (DataObject.class);
            
            if (obj != null) {
                if (obj.isTemplate ()) {
                    // on normal nodes stop recursion
                    return new Node[] { new DataShadowFilterNode (n, Children.LEAF, nodeName) };
                }
            
                if (acceptDataObject (obj)) {
                    // on folders use normal filtering
                    return new Node[] { new DataShadowFilterNode (n, new DataShadowFilterChildren (n), nodeName) };
                }
            }
            return new Node[] {};
        }

    }
    

    private static class DataShadowFilterNode extends FilterNode {
        
        private String name;
        
        public DataShadowFilterNode (Node or, org.openide.nodes.Children children, String name) {
            super (or, children);
            this.name = name;
            disableDelegation(FilterNode.DELEGATE_SET_DISPLAY_NAME);
        }
        
        public String getDisplayName() {
            return name;
        }
        
        // issue 29867, rename should be prohibited
        public boolean canRename () {
            return false;
        }
        
    }
    

    /** Updates description to reflect the one associated with given object.
    * @param obj object
    */
    private void updateDescription (DataObject obj) {
        java.net.URL url = null;
        if (obj != null) {
            url = TemplateWizard.getDescription (obj);
        }
        java.awt.CardLayout card = (java.awt.CardLayout)browserPanel.getLayout();
        if (url != null && 
            getExplorerManager().getSelectedNodes().length != 0) {
            if (browser != null) {
                browser.setURL(url);
                if (!browser.isVisible()) {
                    card.show (browserPanel, "browser"); // NOI18N
                }
            }
        } else {
            card.show (browserPanel, "noBrowser"); // NOI18N
        }
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the FormEditor.
     */
    private void initComponents() {//GEN-BEGIN:initComponents
        java.awt.GridBagConstraints gridBagConstraints;

        browserPanel = new javax.swing.JPanel();
        noBrowser = new javax.swing.JLabel();
        templatesLabel = new javax.swing.JLabel();
        browserLabel = new javax.swing.JLabel();

        setLayout(new java.awt.GridBagLayout());

        setPreferredSize(new java.awt.Dimension(0, 0));
        browserPanel.setLayout(new java.awt.CardLayout());

        // same background as html browser to avoid flicking
        noBrowser.setBackground(javax.swing.UIManager.getDefaults().getColor("EditorPane.background"));
        noBrowser.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        // bigger minimum size then usual to behave well in card
        // layout together with HtmlBrowser
        noBrowser.setMinimumSize(new java.awt.Dimension(0, 25));
        noBrowser.setOpaque(true);
        browserPanel.add(noBrowser, "noBrowser");

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weighty = 0.5;
        add(browserPanel, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0);
        add(templatesLabel, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0);
        add(browserLabel, gridBagConstraints);

    }//GEN-END:initComponents


    private void nameFocusGained (java.awt.event.FocusEvent evt) {//GEN-FIRST:event_nameFocusGained
    }//GEN-LAST:event_nameFocusGained
    private void templatesTreeValueChanged (javax.swing.event.TreeSelectionEvent evt) {//GEN-FIRST:event_templatesTreeValueChanged
    }//GEN-LAST:event_templatesTreeValueChanged

    /** Handles explorer manager property changes. */
    public void propertyChange(java.beans.PropertyChangeEvent evt) {
        if (evt.getPropertyName() == ExplorerManager.PROP_SELECTED_NODES && listener != null) {
            listener.stateChanged (new ChangeEvent (this));
            
            updateDescription (template);
        }
    }


    private void packagesListValueChanged (javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_packagesListValueChanged
    }//GEN-LAST:event_packagesListValueChanged


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel browserLabel;
    private javax.swing.JPanel browserPanel;
    private javax.swing.JLabel noBrowser;
    private javax.swing.JLabel templatesLabel;
    // End of variables declaration//GEN-END:variables
    private TemplatesTreeView treeView;
    private HtmlBrowser browser;

    /** Should the data object be displayed or not?
    * @param obj the data object
    * @return true if the object should be displayed,
    *    false otherwise
    */
    public boolean acceptDataObject(DataObject obj) {
        if (obj instanceof DataFolder) {
            Object o = obj.getPrimaryFile ().getAttribute ("simple"); // NOI18N
            return o == null || Boolean.TRUE.equals (o);
        } else {
            return obj.isTemplate();
        }
    }

    /** Prepares decription area with html browser inside.
     * Executed in other then event dispatch thread.
     */
    public void construct() {
        initData = new InitData();
        initData.browser = new HtmlBrowser(false, false);
        initData.browser.setName("browser");
        initData.noDescMsg = NbBundle.getBundle(TemplateWizard1.class).
                            getString("MSG_NoDescription");
        initData.noDescBorder = new EtchedBorder();

        // override the Swing default CSS to make the HTMLEditorKit use the
        // same font as the rest of the UI
        
        Component comp = initData.browser.getBrowserComponent();
        if (! (comp instanceof javax.swing.JEditorPane))
            return;

        javax.swing.text.EditorKit kit = ((javax.swing.JEditorPane) comp).getEditorKitForContentType("text/html"); // NOI18N
        if (! (kit instanceof javax.swing.text.html.HTMLEditorKit))
            return;

        javax.swing.text.html.HTMLEditorKit htmlkit = (javax.swing.text.html.HTMLEditorKit) kit;

        // XXX the style sheet is shared by all HTMLEditorKits.  We must
        // detect if it has been tweaked by ourselves or someone else
        // (template description for example) and avoid doing the same
        // thing again
        
        if (htmlkit.getStyleSheet().getStyleSheets() != null)
            return;
        
        javax.swing.text.html.StyleSheet css = new javax.swing.text.html.StyleSheet();
        java.awt.Font f = new javax.swing.JTextArea().getFont();
        css.addRule(new StringBuffer("body { font-size: ").append(f.getSize()) // NOI18N
                    .append("; font-family: ").append(f.getName()).append("; }").toString()); // NOI18N
        css.addStyleSheet(htmlkit.getStyleSheet());
        htmlkit.setStyleSheet(css);
    }

    /** Fills description area using constructed data. Executed in event dispatch thread.
     */
    public void finished() {
        browser = initData.browser;
        browserLabel.setLabelFor(browser);
        browser.getAccessibleContext().setAccessibleName(browserLabel.getText());
        browserPanel.add(browser, "browser");
        updateDescription(template);
        // change loading text to no description text                
        // install same border as html browser have
        noBrowser.setText(initData.noDescMsg);
        noBrowser.setBorder(initData.noDescBorder);
        // we don't need initData anymore, make gc'able
        initData = null;
    }
    
    /** Helper implementation of WizardDescription.Panel for TemplateWizard.Panel1.
    * Provides the wizard panel with the current data--either
    * the default data or already-modified settings, if the user used the previous and/or next buttons.
    * This method can be called multiple times on one instance of WizardDescriptor.Panel.
    * @param settings the object representing wizard panel state, as originally supplied to {@link WizardDescriptor#WizardDescriptor(WizardDescriptor.Iterator,Object)}
    */
    void implReadSettings (Object settings) {
        TemplateWizard wizard = (TemplateWizard)settings;
        wizard.setTitle(org.openide.util.NbBundle.getBundle(TemplateWizard.class).getString("CTL_TemplateTitle"));
        updateRootNode (wizard.getTemplatesFolder ());

        template = wizard.getTemplate ();
        if (template != null && !template.isValid() ) {
            template = null;
        } 

        // now try to find out the path
        // a bit ugly code to do that
        DataObject obj = template;
        DataObject stop = wizard.getTemplatesFolder ();
        final LinkedList ll = new LinkedList ();
        for (;;) {
            if (obj == null) {
                // seems that the template is not one of templates
                break;
            }

            if (obj == stop) {
                // the last object found
                break;
            }

            String key = obj.getNodeDelegate().getName ();
            ll.addFirst(key);
            obj = obj.getFolder();
        }

        RequestProcessor.getDefault ().post (new Runnable () {
            private Node selection;
            
            public void run () { 
                if (selection == null) {
                    // go thru all the nodes and find
                    Node node = getExplorerManager().getRootContext();
                    java.util.ListIterator it = ll.listIterator();
                    while (it.hasNext()) {
                        String name = (String)it.next ();
                        node = node.getChildren ().findChild (name);
                        if (node == null) {
                            // end it
                            node = getExplorerManager().getRootContext();
                            break;
                        }
                    }
                    
                    selection = node;
                    
                    // execute the second pass
                    SwingUtilities.invokeLater (this);
                } else {
                    // second pass, executed in AWT thread
                    try {
                        getExplorerManager().setSelectedNodes(new Node[] {selection});
                    } catch (java.beans.PropertyVetoException evt) {
                        // ignore
                    }
                }
            }
        }, 300, Thread.MIN_PRIORITY);
    }

    /** Helper implementation of WizardDescription.Panel for TemplateWizard.Panel1.
    * Provides the wizard panel with the opportunity to update the
    * settings with its current customized state.
    * Rather than updating its settings with every change in the GUI, it should collect them,
    * and then only save them when requested to by this method.
    * Also, the original settings passed to {@link #readSettings} should not be modified (mutated);
    * rather, the (copy) passed in here should be mutated according to the collected changes.
    * This method can be called multiple times on one instance of WizardDescriptor.Panel.
    * @param settings the object representing a settings of the wizard
    */
    void implStoreSettings (Object settings) {
        if (template != null) {
            TemplateWizard wizard = (TemplateWizard)settings;
            if (wizard.getTemplate() != template) {
                // if template has changed then set target step names and index to default
                Component c = wizard.targetChooser().getComponent();
                if (c instanceof JComponent) {
                    ((JComponent)c).putClientProperty(PROP_CONTENT_DATA, new String[] { c.getName() });
                    ((JComponent)c).putClientProperty(PROP_CONTENT_SELECTED_INDEX, new Integer(0));
                }
            } else {
                // bugfix #27939, if template isn't changed and PROP_CONTENT_DATA no set => set it
                Component c = wizard.targetChooser().getComponent();
                if (c instanceof JComponent) {
                    if (((JComponent)c).getClientProperty (PROP_CONTENT_DATA) == null) {
                        ((JComponent)c).putClientProperty(PROP_CONTENT_DATA, new String[] { c.getName() });
                        ((JComponent)c).putClientProperty(PROP_CONTENT_SELECTED_INDEX, new Integer(0));
                    }
                }
            }
            wizard.setTemplateImpl (template, false);
        }
    }

    /** Helper implementation of WizardDescription.Panel for TemplateWizard.Panel1.
    * Test whether the panel is finished and it is safe to proceed to the next one.
    * If the panel is valid, the "Next" (or "Finish") button will be enabled.
    * @return true if the user has entered satisfactory information
    */
    boolean implIsValid () {
        boolean enable = false;
        Node[] n = getExplorerManager().getSelectedNodes();
        if (n.length == 1) {
            template = (DataObject)n[0].getCookie (DataObject.class);
            enable = template != null && template.isTemplate();
        }
        return enable;
    }

    /** Add a listener to changes of the panel's validity.
    * @param l the listener to add
    * @see #isValid
    */
    void addChangeListener (ChangeListener l) {
        if (listener != null) throw new IllegalStateException ();
        listener = l;
    }

    /** Remove a listener to changes of the panel's validity.
    * @param l the listener to remove
    */
    void removeChangeListener (ChangeListener l) {
        listener = null;
    }

    
    /** Model for displaying only objects till template.
    */
    private static final class TemplatesModel extends NodeTreeModel {
        TemplatesModel() {}
        
        public int getChildCount (Object o) {
            Node n = Visualizer.findNode(o);
            DataObject obj = (DataObject)n.getCookie (DataObject.class);

            return obj == null || obj.isTemplate () ? 0 : super.getChildCount (o);
        }

        public boolean  isLeaf (Object o) {
            Node n = Visualizer.findNode(o);
            DataObject obj = (DataObject)n.getCookie (DataObject.class);

            return obj == null || obj.isTemplate ();
        }
    }

    /** Specialized tree view for templates, non editable and with proper
     * border */
    private static final class TemplatesTreeView extends BeanTreeView {
        TemplatesTreeView() {
            tree.setEditable(false);
            // install proper border
            setBorder((Border)UIManager.get("Nb.ScrollPane.border")); // NOI18N
        }
        
        protected NodeTreeModel createModel() {
            return new TemplatesModel();
        }
    }
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.