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.
 */
/*
 * InplaceEditor.java
 *
 * Created on December 22, 2002, 2:50 PM
 */
package org.openide.explorer.propertysheet;
import java.awt.Component;
import java.awt.event.*;
import java.beans.PropertyEditor;
import javax.swing.JComponent;
import javax.swing.KeyStroke;
/** Interface defining the contract of reusable inline cell editors for
 *  properties.  Generally, this interface will be implemented
 *  on a component subclass.  Note
 *  that such components do not have to be concerned about providing
 *  a custom editor button for properties with custom property
 *  editors.  If needed, the rendering infrastructure will provide
 *  one.
 * 

Inplace editors are designed to be reusable - that is, a single * instance may be reconfigured and reused to edit multiple properties * over its lifespan. The connect() and clear() * methods provide a means of configuring an instance to represent a * property, and then de-configure it when it is no longer needed. The * typical lifecycle of an inplace editor is as follows:

  1. The * user clicks a property in the property sheet.
  2. The property * sheet identifies the property clicked, and locates the correct * inplace editor (either a default one or a custom implementation supplied * by the property or property editor).
  3. connect() is * called to configure the editor
  4. The component returned from * getComponent() is displayed on screen and given focus
  5. *
  6. The user enters text or otherwise manipulates the component to change * the value
  7. When the component determines that the user has * either concluded editing (usually pressing Enter) or cancelled editing * (pressing Escape), the inplace editor fires ACTION_SUCCESS * or ACTION_FAILURE
  8. The property sheet detects this * action event and removes the editor component
  9. The property sheet * updates the property
  10. The property sheet calls clear() * to dispose of any state or references held by the inplace editor
*

If you implement this interface to provide a custom inplace * editor for a particular property, it is wise to also write a * custom PropertyEditor whose paint() method will * paint an image identical to what your editor looks like when * it is instantiated. The simplest way to do this is to create * a renderer instance of your inplace editor, and use it in the * paint() method of your property editor. *

The methods of this interface should never * be called from any thread except the AWT event thread. The backing * implementation is not thread-safe. This includes ActionEvents * fired by instances of InplaceEditor. *

In no cases should an instance of InplaceEditor * attempt to directly update the value of the represented property * or property editor. If the property should be updated, ensure * that getValue() will return the correct value, and * fire the action command COMMAND_SUCCESS. Implementations * should also not assume that because one of these events has been * fired, that therefore the property editor has been updated with * the new value. Components that display inplace editors * are responsible for the timing of and policy for updates to the represented * properties. Inplace editors merely display the contents of a property * editor, provide a way for the user to edit that value, and notify * the infrastructure when the user has made a change. *

Standard implementations of this interface for text entry, combo * boxes and checkboxes are provided by the property sheet infrastructure. * There are several ways to provide a custom inplace editor for use in * the property sheet:

  • Globally - a module supplying a * property editor implementing ExPropertyEditor for a given class may call * PropertyEnv.registerInplaceEditorFactory(InplaceEditor.Factory) * in its attachEnv() method. * When the user invokes an editor operation, the returned inplace editor * will be used.
  • On a per-property basis - A * Node.Property may provide a custom inplace editor via hinting. * To do this, the Node.Property instance should return an * instance of InplaceEditor from getValue * ("inplaceEditor")
* If both methods are used on the same property, the inplace editor provided * by the per-property hint takes precedence. * @author Tim Boudreau */ public interface InplaceEditor { /** Action command that tells the property sheet to update * the property's value with the value from this inplace editor and close * the inplace editor. */ public static final String COMMAND_SUCCESS="success"; //NOI18N /** Action command that tells the property sheet that editing * is completed, but the value should not be updated, the * editor should simply be removed. */ public static final String COMMAND_FAILURE="failure"; //NOI18N /** Connect this editor with a property editor. The * PropertyEditor instance will already be * initialized with the initial value, and if it is an * instance of ExPropertyEditor, ExPropertyEditor.attachEnv(env) * will already have been called. The PropertyEnv * instance is passed to allow rendering hints to be passed to * the InplaceEditor instance.

Implementations * which may be connected to PropertyEditor instances * that do not implement ExPropertyEditor must handle * the case that the env property may be null. * @param pe The property editor * @param env An instance of PropertyEnv, if the editor is an instance of ExPropertyEditor, * or null if it is not */ public void connect (PropertyEditor pe, PropertyEnv env); /** Returns the physical inplace editor component that should be displayed * on-screen. Typical implementations of this * interface are JComponent subclasses which implement this interface * and simply return this from this method. If you * implement this interface separately from the inplace editor * component, it is expected that the same component instance * will be returned from this instance from the first time * connect() is called, until such a time as clear() * is called. * @return The component that should be displayed to the user to edit the property */ public JComponent getComponent(); /** Dispose of any state and references to the property or value being * edited, to avoid memory leaks due to held references. The property display * code will call this once an inplace editor component has been closed. * A call to this method should return the inplace editor to the state it * is in after its constructor is called. */ public void clear(); /** Returns the value currently displayed or selected in the editor. This * may or may not correspond to the current value of the Property being * represented, and may not represent a valid final value for the property, * but rather represents the edit in progress.

This method may return * a String, in which case the property editor will be updated * using its setAsText() method, and the value taken from the * property editor. Implementations are free to also return either null when * appropriate, a String appropriate for use with the property editor's * setAsText() method, or an object instance compatible with the property in question's * setValue() method. * @return The value currently shown in the editor component provided by * getComponent() */ public Object getValue(); /** Set the value to be displayed in the inplace editor. Implementations * should take care to avoid triggering a property change event in the * property editor connected to this inplace editor. This method is used * to restore the partial value of an editor in the case that some * external event causes it to be temporarily removed.

This method * is optional, and primarily useful for editors that support text entry. * Editors which do not support text entry may supply an empty implementation * of this method.

It is required that setValue() for * a given InplaceEditor be able to handle any possible * type that it can return from getValue(), since it is * used to temporarily cache and then restore the value mid-edit. * @param o The value that should be displayed in the editor component. This * should be an object the component is capable of displaying. It may be * a String or any other object type, provided the component is capable * of displaying it. This method will only ever be called with a value * object supplied from getValue(), so this method should * be compatible with anything that getValue() on a given * InplaceEditor implementation may return */ public void setValue (Object o); /** Indicates whether an inplace editor supports the direct entry of text or not. * In particular, this method is used to support managing the background * color of the editor component. The default selection color is * used by the property sheet to indicate selection in the property sheet. Editors * supporting text entry should not have their background color set to * the default selection color, so that the user may distinguish selected * text (which would otherwise have the same background color whether it * were selected or not). * @return True if the editor component supplied by getComponent() supports * direct text entry by the user. */ public boolean supportsTextEntry (); /** Restore the inplace editor to the value returned by the property editor's * getValue() method, discarding any edits. * @throws NullPointerException If called before a call to connect() or after a call to * clear(), since in that case the property editor is null. */ public void reset (); /** Add an action listener to the InplaceEditor. Note that the * source property for ActionEvents fired by an InplaceEditor * must be an instance of InplaceEditor. The * property sheet infrastructure will recognize two action * commands: COMMAND_SUCCESS and COMMAND_FAILURE. * Other action events * (such as may be generated by a component subclass implementing * this interface) may be fired, but will be ignored by the * property sheet infrastructure. * @param al The action listener to add */ public void addActionListener (ActionListener al); /** Remove an action listener from an InplaceEditor. * @param al The action listener to remove */ public void removeActionListener (ActionListener al); /** Keystrokes that should be ignored by the containing component when * this inplace editor is open, even if they are in the InputMap * of the container.

* JTable (and potentially other components) will respond to * keystrokes sent to an embedded component. In particular, this * is a problem in JDK 1.4 with embedded JComboBoxes - the down * arrow key, used for combo box navigation, also changes the selection * and closes the editor. Since it is not always possible to determine reliably the * keystrokes an inplace editor will consume at instantiation * time, this allows them to be specified explicitly, so the table * knows what to ignore. * @return The keystrokes a container of the editor component should ignore even if they * are mapped to actions in it. */ public KeyStroke[] getKeyStrokes(); /** Get the java.beans.PropertyEditor * instance associated with this * inplace editor. For efficiency, client code uses * this method to cache the property editor being * used, rather than perform gratuitous lookups of the * property editor on the property it represents. * Inplace editor implementations are expected to cache * the property editor they are initialized with until clear() * is called. * @return The property editor this InplaceEditor represents */ public PropertyEditor getPropertyEditor(); /** Inplace editors cache the property model used to update a * property value at the conclusion of editing. After a call to * setPropertyModel() this method should return the * property model that should be updated with the value from this * inplace editor. After a subsequent call to clear() * this method should return null.

Under no circumstances * should an InplaceEditor implementation attempt to modify the * property model - this is the job of the infrastructure that * instantiated the InplaceEditor. * @return The property model representing the property being edited */ public PropertyModel getPropertyModel(); /** Set the property model that should be updated in the event of a * change. * @param pm The property model this inplace editor will represent */ public void setPropertyModel(PropertyModel pm); /** Returns true if a component is one the inplace editor instantiated. * The property sheet tracks focus and will close an inplace editor * if focus is lost to an unknown component. Since inplace editors may * instantiate popup components that can receive focus, if focus is * lost while an inplace editor is open, the property sheet will query * the current inplace editor to ensure that the recipient of focus is * truly not a child of the inplace editor. For most InplaceEditor * implementations, it is safe simply to return false from this method. * @param c A component which has received focus * @return True if the passed component was instantiated by the inplace editor as part of * its normal operation (for example, a popup which is not a child of * whatever is returned from getComponent()in the component * hierarchy, but which is effectively part of the editor). */ public boolean isKnownComponent (Component c); /** A factory for inplace editor instances. A module may provide a property * editor which provides a custom inplace editor for any properties * of the type it edits. This is accomplished as follows:

  • The * property editor must implement ExPropertyEditor.
  • * In the attachEnv() method of that interface, it must call * env.registerInplaceEditorFactory(), passing an instance * of InplaceEditor.Factory. If a user attempts to edit * the property, the inplace editor returned from Factory.getInplaceEditor() * will be used.
*

A note about using InplaceEditor instances to render properties: * If a custom property editor is, as is encouraged, using an instance of its * InplaceEditor to paint the value rendered in table cells, this method * must not return the instance being used for rendering - that instance * may be reconfigured at any time with a different value in order to paint * another cell on the property sheet. */ public interface Factory { /** Fetch or create an inplace editor instance. The system guarantees that * there will never be more than one open inplace editor at a time, so it is * safe to return the same static instance repeatedly from this method - when the * editor is opened, it will be configured for the property it is editing. * The optimal approach to implementing this method is to create the editor * on the first call, and maintain a reference to it using a static field, * so a single instance may be shared, but hold the reference to it using * java.lang.ref.WeakReference or * java.lang.ref.SoftReference, so that the instance may be * garbage collected if it is no longer needed. * @return An inplace editor instance */ public InplaceEditor getInplaceEditor (); } }

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