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-2004 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.openide.src.nodes;

import java.beans.*;
import java.util.Collection;
import java.util.Vector;

import org.openide.actions.*;
import org.openide.nodes.*;
import org.openide.src.*;
import org.openide.src.nodes.*;
import org.openide.util.actions.SystemAction;
import org.openide.util.datatransfer.NewType;

/** The default implementation of the hierarchy nodes factory.
* Uses the standard node implementations in this package.
* @author Petr Hamernik
*/
public class DefaultFactory extends Object implements ElementNodeFactory, IconStrings {
    /** Default instance of the factory with read-write properties. */
    public static final DefaultFactory READ_WRITE = new DefaultFactory(true);

    /** Default instance of the factory with read-only properties. */
    public static final DefaultFactory READ_ONLY = new DefaultFactory(false);

    /**
     * Tag for fields category node.
     */
    private static final Object CATEGORY_FIELDS = new Object();
    
    /**
     * Tag for "Method" category node.
     */
    private static final Object CATEGORY_METHODS = new Object();
    
    /**
     * Tag for "Constructors" category node.
     */
    private static final Object CATEGORY_CONSTRUCTORS = new Object();
    
    private static final Collection CLASS_CATEGORIES;

    private static final Collection INTERFACE_CATEGORIES;
    
    private static final int FILTER_CATEGORIES = 0x1000;

    static {
        CLASS_CATEGORIES = new Vector(3, 0);
        CLASS_CATEGORIES.add(CATEGORY_FIELDS);
        CLASS_CATEGORIES.add(CATEGORY_CONSTRUCTORS);
        CLASS_CATEGORIES.add(CATEGORY_METHODS);
        
        INTERFACE_CATEGORIES = new Vector(2, 0);
        INTERFACE_CATEGORIES.add(CATEGORY_FIELDS);
        INTERFACE_CATEGORIES.add(CATEGORY_METHODS);
    }

    /** Should be the element nodes read-only or writeable
    * (properties, clipboard operations,...)
    */
    private boolean writeable;

    /** Create a new factory.
    * @param writeable true if the produced nodes
    * should have writable properties
    * @see ElementNode#writeable
    */
    public DefaultFactory(boolean writeable) {
        this.writeable = writeable;
    }

    /* Test whether this factory produces writeable nodes.
    * @return true if so
    */
    public boolean isWriteable() {
        return writeable;
    }

    /* Returns the node asociated with specified element.
    * @return ElementNode
    */
    public Node createMethodNode (final MethodElement element) {
        return new MethodElementNode(element, writeable);
    }

    /* Returns the node asociated with specified element.
    * @return ElementNode
    */
    public Node createConstructorNode (final ConstructorElement element) {
        return new ConstructorElementNode(element, writeable);
    }

    /* Returns the node asociated with specified element.
    * @return ElementNode
    */
    public Node createFieldNode (final FieldElement element) {
        return new FieldElementNode(element, writeable);
    }

    /* Returns the node asociated with specified element.
    * @return ElementNode
    */
    public Node createInitializerNode (final InitializerElement element) {
        return new InitializerElementNode(element, writeable);
    }

    /* Returns the node asociated with specified element.
    * @return ElementNode
    */
    public Node createClassNode (ClassElement element) {
        return new ClassElementNode(element, createClassChildren(element), writeable);
    }

    /** Create children for a class node.
    * Could be subclassed to customize, e.g., the ordering of children.
    * The default implementation used {@link ClassChildren}.
    * @param element a class element
    * @return children for the class element
    */
    protected Children createClassChildren(ClassElement element) {
        return createClassChildren( element, writeable ? READ_WRITE : READ_ONLY );
    }

    /** Create children for a class node, with specified factory.
    * The default implementation used {@link ClassChildren}.
    * @param element a class element
    * @param factory the factory which will be used to create children
    * @return children for the class element
    */
    final protected Children createClassChildren(ClassElement element, ElementNodeFactory factory ) {

        if (ElementNode.sourceOptions.getCategoriesUsage()) {
            ClassChildren children = new CategorizingChildren(factory, element, writeable);
            ClassElementFilter filter = new ClassElementFilter();
            filter.setOrder(new int[] { 
                    SourceElementFilter.CLASS, 
                    SourceElementFilter.INTERFACE,
                    FILTER_CATEGORIES
            });
            children.setFilter(filter);
            return children;
        }
        else {
            return new ClassChildren(factory, element);
        }
    }

    /* Creates and returns the instance of the node
    * representing the status 'WAIT' of the DataNode.
    * It is used when it spent more time to create elements hierarchy.
    * @return the wait node.
    */
    public Node createWaitNode () {
        AbstractNode n = new AbstractNode(Children.LEAF);
        n.setName(ElementNode.bundle.getString("Wait"));
        n.setIconBase(WAIT);
        return n;
    }

    /* Creates and returns the instance of the node
    * representing the status 'ERROR' of the DataNode
    * @return the error node.
    */
    public Node createErrorNode () {
        AbstractNode n = new AbstractNode(Children.LEAF);
        n.setName(ElementNode.bundle.getString("Error")); // NO18N
        n.setIconBase(ERROR);
        return n;
    }

    /** Array of the actions of the category nodes. */
    private static final SystemAction[] CATEGORY_ACTIONS = new SystemAction[] {
		/*
                SystemAction.get(CopyAction.class),
		*/
                SystemAction.get(PasteAction.class),
                null,
                SystemAction.get(NewAction.class),
                null,
                SystemAction.get(ToolsAction.class),
                SystemAction.get(PropertiesAction.class)
            };

    /** Filters under each category node */
    static final int[][] FILTERS = new int[][] {
                                       { ClassElementFilter.FIELD },
                                       { ClassElementFilter.CONSTRUCTOR },
                                       { ClassElementFilter.METHOD },
                                   };

    /** The names of the category nodes */
    static final String[] NAMES = new String[] {
                                      ElementNode.bundle.getString("Fields"), // NO18N
                                      ElementNode.bundle.getString("Constructors"), // NO18N
                                      ElementNode.bundle.getString("Methods"), // NO18N
                                  };

    /** The short descriptions of the category nodes */
    static final String[] SHORTDESCRS = new String[] {
                                            ElementNode.bundle.getString("Fields_HINT"), // NO18N
                                            ElementNode.bundle.getString("Constructors_HINT"), // NO18N
                                            ElementNode.bundle.getString("Methods_HINT"), // NO18N
                                        };

    /** Array of the icons used for category nodes */
    static final String[] CATEGORY_ICONS = new String[] {
                                               FIELDS_CATEGORY, CONSTRUCTORS_CATEGORY, METHODS_CATEGORY
                                           };

    /*
     * Simple descendant of ClassChildren that distributes nodes from the class to various
     * categories. Since - when categories are used - only innerclass, inner interface
     * and categories can be displayed under 
     */
    static class CategorizingChildren extends ClassChildren {
        boolean writeable;
        
        static {
            ClassChildren.propToFilter.put(ElementProperties.PROP_CLASS_OR_INTERFACE, 
            new Integer(FILTER_CATEGORIES));
        }
        
        CategorizingChildren(ElementNodeFactory factory, ClassElement data, boolean wr) {
            super(factory, data);
            writeable = wr;
        }
        
        protected Node[] createNodes(Object key) {
            if (key == CATEGORY_FIELDS) {
                return new Node[] {
                        new ElementCategoryNode(0, factory, element, writeable)
                };
            } else if (key == CATEGORY_METHODS) {
                return new Node[] {
                        new ElementCategoryNode(2, factory, element, writeable)
                };
            } else if (key == CATEGORY_CONSTRUCTORS) {
                return new Node[] {
                    new ElementCategoryNode(1, factory, element, writeable)
                };
            }
            return super.createNodes(key);
        }
        
        protected Collection getKeysOfType(int type) {
            if (type != FILTER_CATEGORIES)
                return super.getKeysOfType(type);
            if (element.isClassOrInterface()) {
                return CLASS_CATEGORIES;
            } else {
                return INTERFACE_CATEGORIES;
            }
        }
    }
    
    /**
    * Category node - represents one section under class element node - fields,
    * constructors, methods.
    */
    static class ElementCategoryNode extends AbstractNode {

        /** The class element for this node */
        ClassElement element;

        /** The type of the category node - for new types. */
        int newTypeIndex;
        
        /** Create new element category node for the specific category.
        * @param index The index of type (0=fields, 1=constructors, 2=methods)
        * @param factory The factory which is passed down to the class children object
        * @param element the class element which this node is created for
        */
        ElementCategoryNode(int index, ElementNodeFactory factory, ClassElement element, boolean writeable) {
            this(index, new ClassChildren(factory, element));
            this.element = element;
            newTypeIndex = writeable ? index : -1;
            switch (index) {
            case 0: setName("Fields"); break; // NOI18N
            case 1: setName("Constructors"); break; // NOI18N
            case 2: setName("Methods"); break; // NOI18N
            }
        }

        /** Create new element node.
        * @param index The index of type (0=fields, 1=constructors, 2=methods)
        * @param children the class children of this node
        */
        private ElementCategoryNode(int index, ClassChildren children) {
            super(children);
            setDisplayName(NAMES[index]);
            setShortDescription (SHORTDESCRS[index]);
            ClassElementFilter filter = new ClassElementFilter();
            filter.setOrder(FILTERS[index]);
            children.setFilter(filter);
            systemActions = CATEGORY_ACTIONS;
            setIconBase(CATEGORY_ICONS[index]);
        }

	/** Disables copy for the whole category. Sub-elements need to be selected individually.
	 */
	public boolean canCopy() {
	    return false;
	}

        /* Get the new types that can be created in this node.
        * @return array of new type operations that are allowed
        */
        public NewType[] getNewTypes() {
            if (!SourceEditSupport.isWriteable(element)) {
                return new NewType[0];
            }
            switch (newTypeIndex) {
            case 0:
                return new NewType[] {
                           new SourceEditSupport.ElementNewType(element, (byte) 1)
                       };
            case 1:
                return new NewType[] {
                           new SourceEditSupport.ElementNewType(element, (byte) 0),
                           new SourceEditSupport.ElementNewType(element, (byte) 2)
                       };
            case 2:
                return new NewType[] {
                           new SourceEditSupport.ElementNewType(element, (byte) 3)
                       };
            default:
                return super.getNewTypes();
            }
        }

        public void createPasteTypes(java.awt.datatransfer.Transferable t, java.util.List s) {
            Node n = getParentNode();
            if (n == null || !(n instanceof ClassElementNode)) {
                return;
            }
            ((ClassElementNode)n).createPasteTypes(t, s);
        }
    }

}
... 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.