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

package org.netbeans.spi.looks;

import java.awt.Component;
import java.awt.datatransfer.Transferable;
import java.io.IOException;
import java.util.*;

import javax.swing.Action;

import org.openide.nodes.Node;
import org.openide.util.HelpCtx;
import org.openide.util.Lookup;
import org.openide.util.datatransfer.NewType;
import org.openide.util.datatransfer.PasteType;
import org.netbeans.modules.looks.LookListener;
import org.netbeans.modules.looks.LookEvent;


/**
 * Base class for all Looks. All methods in the class provide
 * neutral behavior (i.e. do nothing, rerurn null or false).
* Extending this class in order to implement * a Look requires overriding all methods which should provide some * functionality. You may also consider subclassing * the adaptor class {@link org.netbeans.spi.looks.DefaultLook * DefaultLook class}, which provides basic implementations for * finding Icons and Actions. *

* Most methods take a Lookup as parameter. This lookup represents environement * associated with given represented object. This environement usually * contains data from the {@link #getLookupItems} method. However if more * looks cooperate on the same represented object it should contain union * of items provided by all cooperating looks. * * @author Petr Hrebejk * @see org.netbeans.spi.looks.DefaultLook */ public abstract class Look extends Object { /** Internal mask for property change */ private static final long PROPERTY_CHANGE = -1; /** Mask for enabling (unmasking) all methods */ public static final long ALL_METHODS = Long.MAX_VALUE; /** Mask for disabling (masking) all methods */ public static final long NO_METHODS = 0; /** Mask for the method {@link org.netbeans.spi.looks.Look#destroy}. */ public static final long DESTROY = 1; /** Mask for the method {@link org.netbeans.spi.looks.Look#rename}. */ public static final long RENAME = DESTROY << 1; /** Mask for firing Cookie events and providing lookup items */ public static final long GET_LOOKUP_ITEMS = RENAME << 1; /** Mask for the method {@link org.netbeans.spi.looks.Look#getDisplayName}. */ public static final long GET_DISPLAY_NAME = GET_LOOKUP_ITEMS << 1; /** Mask for the method {@link org.netbeans.spi.looks.Look#getName}. */ public static final long GET_NAME = GET_DISPLAY_NAME << 1; /** Mask for the method {@link org.netbeans.spi.looks.Look#getShortDescription}. */ public static final long GET_SHORT_DESCRIPTION = GET_NAME << 1; /** Mask for the method {@link org.netbeans.spi.looks.Look#getIcon}. */ public static final long GET_ICON = GET_SHORT_DESCRIPTION << 1; /** Mask for the method {@link org.netbeans.spi.looks.Look#getOpenedIcon}. */ public static final long GET_OPENED_ICON = GET_ICON << 1; /** Mask for the method {@link org.netbeans.spi.looks.Look#getHelpCtx}. */ public static final long GET_HELP_CTX = GET_OPENED_ICON << 1; /** Mask for the method {@link org.netbeans.spi.looks.Look#getChildObjects}. */ public static final long GET_CHILD_OBJECTS = GET_HELP_CTX << 1; /** Mask for the method {@link org.netbeans.spi.looks.Look#getNewTypes}. */ public static final long GET_NEW_TYPES = GET_CHILD_OBJECTS << 1; /** Mask for the method {@link org.netbeans.spi.looks.Look#getActions}. */ public static final long GET_ACTIONS = GET_NEW_TYPES << 1; /** Mask for the method {@link org.netbeans.spi.looks.Look#getContextActions}. */ public static final long GET_CONTEXT_ACTIONS = GET_ACTIONS << 1; /** Mask for the method {@link org.netbeans.spi.looks.Look#getDefaultAction}. */ public static final long GET_DEFAULT_ACTION = GET_CONTEXT_ACTIONS << 1; /** Mask for the method {@link org.netbeans.spi.looks.Look#getPropertySets}. */ public static final long GET_PROPERTY_SETS = GET_DEFAULT_ACTION << 1; /** Mask for the method {@link org.netbeans.spi.looks.Look#getCustomizer}. */ public static final long GET_CUSTOMIZER = GET_PROPERTY_SETS << 1; /** Mask for the method {@link org.netbeans.spi.looks.Look#canRename}. */ public static final long CAN_RENAME = GET_CUSTOMIZER << 1; /** Mask for the method {@link org.netbeans.spi.looks.Look#canDestroy}. */ public static final long CAN_DESTROY = CAN_RENAME << 1; /** Mask for the method {@link org.netbeans.spi.looks.Look#canCopy}. */ public static final long CAN_COPY = CAN_DESTROY << 1; /** Mask for the method {@link org.netbeans.spi.looks.Look#canCut}. */ public static final long CAN_CUT = CAN_COPY << 1; /** Mask for the method {@link org.netbeans.spi.looks.Look#getPasteTypes}. */ public static final long GET_PASTE_TYPES = CAN_CUT << 1; /** Mask for the method {@link org.netbeans.spi.looks.Look#getDropType}. */ public static final long GET_DROP_TYPE = GET_PASTE_TYPES << 1; /** Mask for the method {@link org.netbeans.spi.looks.Look#clipboardCopy}. */ public static final long CLIPBOARD_COPY = GET_DROP_TYPE << 1; /** Mask for the method {@link org.netbeans.spi.looks.Look#clipboardCut}. */ public static final long CLIPBOARD_CUT = CLIPBOARD_COPY << 1; /** Mask for the method {@link org.netbeans.spi.looks.Look#drag}. */ public static final long DRAG = CLIPBOARD_CUT << 1; /** Mask for the method {@link org.netbeans.spi.looks.Look#hasCustomizer}. */ public static final long HAS_CUSTOMIZER = DRAG << 1; private ListenerCache listenerCache; // Programmatic name of the look private String name; static { // initialize module private access to this package org.netbeans.modules.looks.Accessor.DEFAULT = new AccessorImpl (); } // Constructors ------------------------------------------------------------ /** Creates new instance of look does no work. * @param name the name to assign to the look. */ protected Look( String name ) { this.name = name; } // Identification methods -------------------------------------------------- /** Returns name of the look. This name should identify the look. * @return Name of the look. */ public final String getName() { return name; } /** The human presentable name of the look. Default implementation * calls getName(); * @return human presentable name */ public String getDisplayName() { return getName(); } public String toString() { return getName(); } // General methods --------------------------------------------------------- /** * Overriding this method permits registering listeners on represented objects. *

* If given instance is used in many places (e.g. multiple views are using * the look for representing the given object or when the look is used as a sublook * in multiple composite looks) attachTo will only be called once per * represented object. *

* Implementors may not wait for any other threads at it may be potentially called * from internal lock. * * @param representedObject Represented object the look should work with. * @throws ClassCastException When the represented object is unacceptable * for the look due to wrong class * @throws IllegalArgumentException When the represented object is * unacceptable for other reason than class cast. * */ protected void attachTo( Object representedObject ) { } /** * This method is called when listening on represeted object is no * longer needed. Make sure to deregister all listeners registered * in {@link #attachTo} method.
* If given instance is used in many places (e.g. more views are using * the look for representing given object or when the look is used as a sublook * in more composite look) the detachFrom method will only be called once per * reprsented object. *

* Implementors may not wait for any other threads at it may be potentially called * from internal lock. * @param representedObject Represented object to detach from. */ protected void detachFrom( Object representedObject ) { } // Methods for FUNCTIONALITY EXTENSIONS ------------------------------------ /** Allowes for adding new object into the object's environement passed * to other methods as the env parameter. * @param representedObject Parameter is ignored. * @param oldEnv Content of previous environement when called after a change * of environemnt or is empty. * @return null */ public java.util.Collection getLookupItems( Object representedObject, Lookup oldEnv ) { return null; } // Methods for STYLE ------------------------------------------------------- /** Gets the programmatic name of the object. This name shouldn't be * localized.
* Notice that the env parameter may be empty in some cases (e.g. when * call to this methods is performed during serialization) * @param representedObject Represented object the look should work with. * @param env Environement for the represented object. * @return Programmatic name of the object. */ public String getName( Object representedObject, Lookup env ) { return null; } /** Gets localized name of the object. * @param representedObject Represented object the look should work with. * @param env Environement for the represented object. * @return Localized name of the object. */ public String getDisplayName( Object representedObject, Lookup env ) { return null; } /** This method is called when the user renames the object. * @param representedObject Represented object to be renamed. * @param newName The new name set by the user. * @param env Environement for the represented object. */ public void rename( Object representedObject, String newName, Lookup env ) throws IOException { } /** Gets short description for given object. The short description is usually * visualized as a tooltip, but may have another forms as well. * @param representedObject Represented object the look should work with. * @param env Environement for the represented object. * @return A localized short description of the object. */ public String getShortDescription( Object representedObject, Lookup env ) { return null; } /** Find an icon for this object (in the closed state). * @param representedObject Represented object the look should work with. * @param type Constant from {@link java.beans.BeanInfo} * @param env Environement for the represented object. * @return Icon to use to represent the object in the closed state. */ public java.awt.Image getIcon( Object representedObject, int type, Lookup env ) { return null; } /** Find an icon for this object (in the open state). * This icon is used when the object may have children and is expanded. * @param representedObject Represented object the look should work with. * @param type Constant from {@link java.beans.BeanInfo} * @param env Environement for the represented object. * @return Icon to use to represent the object in the open state. */ public java.awt.Image getOpenedIcon( Object representedObject, int type, Lookup env ) { return null; } /** Get context help associated with this object. * @param representedObject Represented object the look should work with. * @param env Environement for the represented object. * @return The context help object (could be null or * {@link org.openide.util.HelpCtx#DEFAULT_HELP}) */ public HelpCtx getHelpCtx( Object representedObject, Lookup env ) { return null; } // Methods for CHILDREN ---------------------------------------------------- /** Gets objects which are children of the represented object in the * hierarchy represented by this Look. * @param representedObject Represented object the look should work with. * @param env Environement for the represented object. * @return List of objects which should be represented as node children of * the node, can return null. */ public List getChildObjects( Object representedObject, Lookup env ) { return null; } /** Decides whether given object should be a leaf. * I.e. if the visual * representation of the object should be expandable. *

* Notice : Implementation of * this method must be consistent with implementation of * {@link #getChildObjects}. * Notice that you can switch the form LEAF to nonLEAF node and vice versa * by calling {@link #fireChange} with parameter {@link #GET_CHILD_OBJECTS}, * which in turn will call * isLeaf(...) and eventually getChildObjects(...) * where you can return new value. * @param representedObject Represented object the look should work with. * @param env Environement for the represented object. * @return true if the object should be unexpandable * false otherwise. */ public boolean isLeaf( Object representedObject, Lookup env ) { return false; } // Methods for ACTIONS & NEW TYPES ----------------------------------------- /** Get the new types that user can create from given object. * For example, a a Java package will permit classes to be added. * @param representedObject Represented object the look should work with. * @param env Environement for the represented object. * @return Array of new type operations that are allowed, * can return null that is equivalent to empty array */ public NewType[] getNewTypes( Object representedObject, Lookup env ) { return null; } /** Get the set of actions associated with the object. * This may be used for in constructing popup menus etc. *

* @param representedObject Represented object the look should work with. * @param env Environement for the represented object. * @return Array of the Actions applicable to the node or null * if actions in {@link org.openide.nodes.NodeOp#getDefaultActions()} should be used. */ public Action[] getActions( Object representedObject, Lookup env ) { return null; } /** Get a special set of actions for situations when this object is displayed * as a context. (E.g. right clicking in the empty area of a tree) * @param representedObject Represented object the look should work with. * @param env Environement for the represented object. * @return Actions for a context. */ public Action[] getContextActions( Object representedObject, Lookup env ) { return null; } /** Get the default action for this object. * This action can but need not be one from the list returned * from {@link #getActions}. * @param representedObject Represented object the look should work with. * @param env Environement for the represented object. * @return Default action, or null if there should be none. */ public Action getDefaultAction( Object representedObject, Lookup env ) { return null; } // Methods for PROPERTIES AND CUSTOMIZER ----------------------------------- /** Get the list of property sets for object. E.g. typically there * may be one for normal Bean properties, one for expert * properties, and one for hidden properties. * @param representedObject Represented object the look should work with. * @param env Environement for the represented object. * @return Property sets for the object, can return null that * is equivalent to empty array */ public Node.PropertySet[] getPropertySets( Object representedObject, Lookup env ) { return null; } /** Check whether the customizer for the represented object is available. * If so, the method * getCustomizer should return non-null value. * * @param representedObject Represented object the look should work with. * @param env Environement for the represented object. * @return true if the customizer is available, false otherwise */ public boolean hasCustomizer( Object representedObject, Lookup env ) { return false; } /** Get the customizer for represented object if available. * @param representedObject Represented object the look should work with. * @param env Environement for the represented object. * @return The component, or null if there is no customizer. */ public Component getCustomizer( Object representedObject, Lookup env ) { return null; } // Methods for CLIPBOARD OPERATIONS ---------------------------------------- /** Test whether this object can be renamed. * If true, {@link #rename} will be called when the user changes the name * of the node. * @param representedObject Represented object the look should work with. * @param env Environement for the represented object. * @return true if the node object be renamed. */ public boolean canRename( Object representedObject, Lookup env ) { return false; } /** Test whether this object can be deleted. * @param representedObject Represented object the look should work with. * @param env Environement for the represented object. * @return True if can be deleted. */ public boolean canDestroy( Object representedObject, Lookup env ) { return false; } /** Test whether this object permits copying. * @param representedObject Represented object the look should work with. * @param env Environement for the represented object. * @return True if so. */ public boolean canCopy( Object representedObject, Lookup env ) { return false; } /** Test whether this object permits cutting. * @param representedObject Represented object the look should work with. * @param env Environement for the represented object. * @return True if so. */ public boolean canCut( Object representedObject, Lookup env ) { return false; } /** Determine which paste operations are allowed when a given * transferable is in the clipboard. For example, a * Java package will permit classes to be pasted into it. * @param representedObject Represented object the look should work with. * @param t The transferable in the clipboard. * @param env Environement for the represented object. * @return Array of operations that are allowed, can return null * that is equivalent to empty array */ public PasteType[] getPasteTypes( Object representedObject, Transferable t, Lookup env ) { return null; } /** Determine if there is a paste operation that can be performed * on provided transferable. Used by drag'n'drop code to check * whether the drop is possible. * @param representedObject Represented object the look should work with. * @param t The transferable. * @param action The drag'n'drop action to do DnDConstants.ACTION_MOVE, * ACTION_COPY, ACTION_LINK. * @param index Index between children the drop occured at or -1 if not specified. * @param env Environement for the represented object. * @return Null if the transferable cannot be accepted or the paste type * to execute when the drop occurs. */ public PasteType getDropType( Object representedObject, Transferable t, int action, int index, Lookup env ) { return null; } /** Called when a object is to be copied to the clipboard. * @param representedObject Represented object the look should work with. * @param env Environement for the represented object. * @return The transferable object representing the content of the clipboard. * @throws java.io.IOException When the copy cannot be performed. */ public Transferable clipboardCopy( Object representedObject, Lookup env ) throws IOException { return null; } /** Called when the object is to be cut to the clipboard. * @param representedObject Represented object the look should work with. * @param env Environement for the represented object. * @return The transferable object representing the content of the clipboard. * @throws java.io.IOException When the copy cannot be performed. */ public Transferable clipboardCut( Object representedObject, Lookup env ) throws IOException { return null; } /** Called when a drag is started with this object. * The object can attach a transfer listener to ExTransferable and * will be then notified about progress of the drag (accept/reject). * @param representedObject Represented object the look should work with. * @param env Environement for the represented object. * @return Transferable to represent this object during a drag. * @throws java.io.IOException If a drag cannot be started. */ public Transferable drag( Object representedObject, Lookup env ) throws IOException { return null; } /** Called when object was destroyed. * @param representedObject Represented object the look should work with. * @param env Environement for the represented object. * @throws java.io.IOException If reflecting the destroy action in underlying data * fails for some reason. */ public void destroy( Object representedObject, Lookup env ) throws IOException { } // Event firing ------------------------------------------------------------ /** Notifies all listeners attached to the representedObject that * result(s) of some method(s) changed. The mask patameter contains * bit mask of the methods. * * @param representedObject the object that has changed * @param mask Bit mask of methods which's result changed. See {@link Look} * for the constants * */ protected final void fireChange( Object representedObject, long mask ) { fireUniversal( mask, representedObject, null ); } /** Notifies all listeners attached to the representedObject that * a property in the PropertySets changed it's value. * * @param representedObject the object that has changed * @param propertyName Name of the property */ protected final void firePropertyChange( Object representedObject, String propertyName ) { fireUniversal( PROPERTY_CHANGE, representedObject, propertyName ); } // Registering look listeners ---------------------------------------------- synchronized void addLookListener( Object representedObject, LookListener listener ) { if ( representedObject != null && ( listenerCache == null || listenerCache.getListenersCount( representedObject ) == 0 ) ) { attachTo( representedObject ); } if ( listenerCache == null ) { listenerCache = new ListenerCache(); } listenerCache.addListener( representedObject, listener ); } synchronized void changeLookListener( Object representedObject, LookListener oldListener, LookListener newListener ) { if ( listenerCache != null ) { listenerCache.changeListener( representedObject, oldListener, newListener ); } } synchronized void removeLookListener( Object representedObject, LookListener listener ) { if ( representedObject != null && listenerCache != null && listenerCache.getListenersCount( representedObject ) == 1 ) { detachFrom( representedObject ); } if ( listenerCache != null /* && listener != null */ ) { listenerCache.removeListener( representedObject, listener ); } } // Package private methods ------------------------------------------------- /** Gets all objects which have some object registred. Used from look and * to fire on all objects and from ProxyLook to fire when selector change * occurs. It returns copy of the cache. */ synchronized Object[] getAllObjects() { Collection allObjects = listenerCache.getAllObjects(); Object objects[] = allObjects.toArray(); return objects; } // Private methods --------------------------------------------------------- private void fireUniversal( long mask, Object representedObject, String propertyName ) { if ( listenerCache == null ) { return; } if ( representedObject == null ) { // Fire on all objects Object [] objects = getAllObjects(); if ( objects == null ) { return; } for( int i = 0; i < objects.length; i++ ) { fireUniversal( mask, objects[i], name ); } } else { // Fire on one object LookEvent evt = mask == PROPERTY_CHANGE ? new LookEvent( representedObject, propertyName ) : new LookEvent( representedObject, mask ); List listeners; synchronized( this ) { listeners = listenerCache.getListeners( representedObject ); } for( int i = 0; i < listeners.size(); i++ ) { if ( mask == PROPERTY_CHANGE ) { ((LookListener)listeners.get( i )).propertyChange( evt ); } else { ((LookListener)listeners.get( i )).change( evt ); } } } } // Innerclasses ------------------------------------------------------------ private static final Object PLACE_HOLDER = new Object(); // Cache of listeners private class ListenerCache { private HashSet allObjectListeners; // Listeners which should listen to all objects private Map obj2l; // Standard listeners: Map|List>> void addListener( Object object, LookListener listener ) { if ( object == null ) { // Listener which wants to know about all objects if ( allObjectListeners == null ) { allObjectListeners = new HashSet(); } if ( listener != null ) { allObjectListeners.add( listener ); } } else { // Listener registered to particular object if ( obj2l == null ) { obj2l = new IdentityHashMap(); } Object l = obj2l.get( object ); if ( l == null ) { // There is nothing in the cache obj2l.put( object, listener == null ? PLACE_HOLDER : listener ); // just add } else { // Something already registered if ( l instanceof LookListener || l == PLACE_HOLDER ) { // One listener List ll = new ArrayList( 2 ); // PENDING make this to array in order to save some memory ll.add( l ); ll.add( listener == null ? PLACE_HOLDER : listener ); obj2l.put( object, ll ); } else { // There are already many listeners ((List)l).add( listener == null ? PLACE_HOLDER : listener ); } } } } void removeListener( Object object, LookListener listener ) { if ( object == null ) { if ( allObjectListeners != null ) { allObjectListeners.remove( listener ); } return; } if ( obj2l == null ) { return; } Object l = obj2l.get( object ); if ( l == PLACE_HOLDER || l instanceof LookListener ) { // Removing the listener from map obj2l.remove( object ); } else if ( l != null ) { // Removing the listener from list List ll = (List)l; ll.remove( listener == null ? PLACE_HOLDER : listener ); if ( ll.size() == 1 ) { obj2l.put( object, ll.get( 0 ) ); // Remove list put last listener instead } } } void changeListener( Object object, LookListener oldListener, LookListener newListener ) { if ( object == null ) { if ( allObjectListeners != null ) { allObjectListeners.remove( oldListener ); allObjectListeners.add( newListener ); } return; } if ( obj2l == null ) { return; } Object l = obj2l.get( object ); if ( l == oldListener ) { obj2l.put( object, newListener == null ? PLACE_HOLDER : newListener ); // Change the listener } else { // Removing the listener from list List ll = (List)l; if ( ll.remove( oldListener ) ) { ll.add( newListener == null ? PLACE_HOLDER : newListener ); } } } List getListeners( Object object ) { if ( object == null ) { throw new IllegalStateException( "Reperesented object is null" ); } List result = new ArrayList( 4 ); if ( allObjectListeners != null ) { result.addAll( allObjectListeners ); } if ( obj2l != null ) { Object l = obj2l.get( object ); if ( l == null ) { // System.err.println( "LOOK : " + Look.this ); // System.err.println( "OBJ : " + object ); } else if ( l instanceof LookListener ) { result.add( l ); } else if ( l == PLACE_HOLDER ) { // Cant fire on placeholder } else { // We need to filter out PLACE_HOLDERs for( Iterator it = ((List)l).iterator(); it.hasNext(); ) { Object listener = it.next(); if ( listener != PLACE_HOLDER ) { result.add( listener ); } } } } return result; } /*@ !! does not count listeners on all objects */ int getListenersCount( Object object ) { if ( object == null ) { throw new IllegalStateException( "Reperesented object is null" ); } if ( obj2l != null ) { Object l = obj2l.get( object ); if ( l == null ) { return 0; } else if ( l == PLACE_HOLDER || l instanceof LookListener ) { return 1; } else { return ((List)l).size(); } } return 0; } Collection getAllObjects() { if ( obj2l == null ) { return null; } else { return obj2l.keySet(); } } } }

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