Interface ILcyCustomizerPanel

All Superinterfaces:
ILcdPropertyChangeSource, ILcdUndoableSource
All Known Subinterfaces:
ILcyCompositeCustomizerPanel
All Known Implementing Classes:
ALcyCustomizerPanel, ALcyDataPropertyCustomizerPanel, ALcyDomainObjectCustomizerPanel, ALcyLayerCustomizerPanel, ALcyModelCustomizerPanel, ALcyShapeCustomizerPanel, TLcyCompositeCustomizerPanel, TLcyCompositeCustomizerTabbedPane, TLcyGXYAsynchronousLayerCustomizerPanel

public interface ILcyCustomizerPanel extends ILcdUndoableSource, ILcdPropertyChangeSource
This interface represents a panel containing a user interface to customize some object. For example, an ILcyCustomizerPanel to customize an ILcdGXYLayer could contain checkboxes to toggle the visible state, editable state, etc. Another example would be a panel to customize the coordinates of the points of a polyline.

Implementations must extend from java.awt.Component or one of its subclasses (e.g. JPanel).

This interface allows storing key-value pairs such as a name and an icon. The mechanism is similar to that of ILcdAction.

The object to customize is set using setObject. applyChanges commits any pending changes. Pending changes are modifications the user has made in the user interface, but that are not yet committed to the actual object. cancelChanges reverts the possible pending changes, and restores the values of the actual object. isChangesPending allows to check if there are any pending changes, isChangesValid allows to check if the pending changes are valid. Whenever the return values of those methods change, a PropertyChangeEvent must be fired.

ALcyCustomizerPanel, ALcyDomainObjectCustomizerPanel, ALcyLayerCustomizerPanel and ALcyModelCustomizerPanel are abstract implementations that facilitate the implementation of an ILcyCustomizerPanel. Their documentation explains how and when they are useful.

Instances of this interface can be obtained by iterating over the ILcyCustomizerPanelFactory objects registered in the Lucy backend. TLcyUserInterfaceManager.getCompositeCustomizerPanelFactory() contains more information on this subject.

Example

Consider the example of an ILcyCustomizerPanel that allows to edit the coordinates of the points of a polyline, by using a text field for every point. As described in the Lucy developer guide, this type of interaction with the TLcySelectionEditorAddOn uses a TLcyDomainObjectContext as the object to customize.

The polyline is set to the ILcyCustomizerPanel, using a TLcyDomainObjectContext, which contains a reference to both the polyline and the ILcdModel of the polyline. The ILcdModel can for example be used to retrieve the coordinate system of the points (ILcdModel.getModelReference).

When the user has changed one of the coordinates using the text field, the panel fires a "changesPending" property change event from false to true. The container holding this ILcyCustomizerPanel can then enable its apply button. When the user clicks the apply button, the method applyChanges is invoked by the external container, which effectively commits the changes to the polyline. The ILcyCustomizerPanel will again fire a "changesPending" event from true to false describing there are no pending changes any more. The panel can also (optionally) fire a TLcdUndoableEvent to describe that the change can be undone. For this example, also the ILcdModel needs to be informed about the change (ILcdModel.elementChanged).

If the cancel button was pressed instead of the apply button, the external container would invoke the cancelChanges method which discards the changes in the text field and reverts it back to the current coordinate of the polyline. Again a "changesPending" event from true to false would be fired.

If the external container holding this ILcyCustomizerPanel preferred not to have an apply and cancel button, it could immediately apply the changes whenever a "changesPending" false to true property change event is received.

  • Field Details

    • NAME

      static final String NAME
      The key used for storing the String display name for the ILcyCustomizerPanel.
      See Also:
    • SHORT_DESCRIPTION

      static final String SHORT_DESCRIPTION
      The key used for storing a short String description for the ILcyCustomizerPanel. This can for example be used as a tooltip text.
      See Also:
    • LONG_DESCRIPTION

      static final String LONG_DESCRIPTION
      The key used for storing a longer String description for the ILcyCustomizerPanel, could for example be used for context-sensitive help.
      See Also:
    • SMALL_ICON

      static final String SMALL_ICON
      The key used for storing a small ILcdIcon, such as TLcdImageIcon.
      See Also:
    • HINT_PINNED

      static final String HINT_PINNED

      The key for a hint to indicate the ILcyCustomizerPanel should remain visible in the UI. The corresponding value should be a Boolean.

      A possible use-case is to avoid removing a customizer panel which contains invalid user input. When the input is invalid, the customizer panel can decide to set the HINT_PINNED to true to indicate the customizer panel should remain visible. When the input becomes valid, the hint can be switched back to false. This avoids the customizer panel gets removed when.

      Note that this is only a hint. It is up to the users of the ILcyCustomizerPanel instances to decide whether they respect the hint or not.

      See Also:
    • HORIZONTAL_ALIGNMENT_HINT

      static final String HORIZONTAL_ALIGNMENT_HINT

      The key for a hint to indicate which horizontal alignment certain types of customizers should use, most notably, text fields and buttons. The corresponding value should be one of:

      An example use case is a text field customizer, where this hint specifies if the text should be left or right aligned. Notable implementations that respect this hint are the text field and button customizer panels created by the factories available in TLcyDataPropertyValueCustomizerPanelFactories.

      See Also:
  • Method Details

    • getValue

      Object getValue(String aKey)
      Gets the property value for the given key.
      Parameters:
      aKey - The key to retrieve the value for.
      Returns:
      the property value for the given key.
      See Also:
    • putValue

      void putValue(String aKey, Object aValue)
      Sets the property value for aKey to aValue. If the value has changed, a PropertyChangeEvent is sent to the listeners. The property name of the event equals the value of aKey.
      Parameters:
      aKey - The key. Should preferably start with an uppercase letter to avoid confusion with regular properties.
      aValue - The value.
      See Also:
    • getPropertyChangeListeners

      PropertyChangeListener[] getPropertyChangeListeners()
      Returns an array of all the PropertyChangeListeners registered on this ILcyCustomizerPanel.
      Returns:
      an array of all the PropertyChangeListeners registered on this ILcyCustomizerPanel, or an empty array if no PropertyChangeListeners are currently registered.
    • addPropertyChangeListener

      void addPropertyChangeListener(String aPropertyName, PropertyChangeListener aListener)

      Adds the given listener for the specific property with name aPropertyName.

      Property change events will be fired for the Bean properties of this class, as well for changes in the key-value pairs of this class (see putValue(String, Object)).

      Parameters:
      aPropertyName - The property name for which aListener will receive events.
      aListener - The listener. It only receives events for the given property name.
      See Also:
    • removePropertyChangeListener

      void removePropertyChangeListener(String aPropertyName, PropertyChangeListener aListener)
      Removes the given PropertyChangeListener for the specific property aPropertyName. This method should be used to remove PropertyChangeListeners that were registered for a specific property name.
      Parameters:
      aPropertyName - The property name.
      aListener - The listener.
      See Also:
    • getPropertyChangeListeners

      PropertyChangeListener[] getPropertyChangeListeners(String aPropertyName)
      Returns an array of all the PropertyChangeListeners registered for aPropertyName.
      Parameters:
      aPropertyName - The property name to retrieve the listeners for.
      Returns:
      an array of all the PropertyChangeListeners registered for aPropertyName, or an empty array if no listeners are registered for that property.
    • isChangesPending

      boolean isChangesPending()
      Returns true if changes are pending. A change is a modification made by the user, e.g., the modified content of a text field. Pending means the method applyChanges was not invoked after the change occurred.

      A property change event "changesPending" must be fired if the return value of this method is changed. This can for example be used to enable/disable an apply button.

      Returns:
      true if there are pending changes, false otherwise.
    • isChangesValid

      boolean isChangesValid()
      Returns true if the pending changes are valid, or if there are no pending changes. Returns false if there are invalid pending changes. A change is a modification made by the user, e.g., the modified content of a text field. Pending means the method applyChanges was not invoked after the change occurred.

      False could for example be returned if the user has entered invalid input that cannot be applied, such as text where a number is expected.

      A property change event "changesValid" must be fired if the return value of this method is changed. This can for example be used to enable/disable an apply button, or to inform the user that he must first correct the invalid content.

      Implementations can ignore this feature by always returning true.

      Returns:
      true if the changes can be applied, false otherwise.
    • canSetObject

      boolean canSetObject(Object aObject)
      Returns true if and only if setObject would not throw an IllegalArgumentException.
      Parameters:
      aObject - The object to check.
      Returns:
      true if setObject would accept the object, false if it would throw an exception.
    • setObject

      void setObject(Object aObject)
      Set the object to be edited. This method should be called before the ILcyCustomizerPanel has been added to any parent AWT container. It can be called afterwards as well however. In this case the user interface should update itself to represent the newly set object.

      A value of null is set to inform this ILcyCustomizerPanel to (temporarily) deinitialize itself, it allows to perform cleanup tasks, such as removing listeners.

      Parameters:
      aObject - The object to be customized, or null to inform that editing is temporarily disabled.
      Throws:
      IllegalArgumentException - In case the given object cannot be edited by this ILcyCustomizerPanel. This exception is thrown if and only if canSetObject returns false for the same aObject.
    • getObject

      Object getObject()
      Returns the object that was set using setObject. This can be null.
      Returns:
      the object that was set using setObject.
      See Also:
    • applyChanges

      boolean applyChanges()
      Updates the set Object according to the current state of the user interface. This means all pending changes are committed.

      If there were any pending changes, so isChangesPending returned true, it should return false after this method has finished, and therefore also a "changesPending" property change event must be fired.

      E.g. consider that a ILcdGXYLayer object is set and a new label text is entered in a text field. When this method is called, the new label text should be set to the ILcdGXYLayer (using ILcdGXYLayer.setLabel).

      Returns:
      True if the changes were applied or if there were no changes, false if the changes could not be applied because they are invalid. In that event, isChangesValid returns false.
    • cancelChanges

      void cancelChanges()
      Updates the user interface state according to the current state of the set Object. Any changes that were made in the user interface but were not yet applied, should be discarded.

      E.g. consider that an ILcdGXYLayer is being edited and a new label text was entered in a text field. When this method is called, the new label text should be cleared and the current label of the ILcdGXYLayer should be put in the text field (ILcdGXYLayer.getLabel()).