org.flexdock.docking.Dockable Maven / Gradle / Ivy
/*
* Copyright (c) 2004 Christopher M Butler
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.flexdock.docking;
import java.awt.Component;
import java.beans.PropertyChangeListener;
import java.util.List;
import java.util.Set;
import org.flexdock.docking.event.DockingListener;
import org.flexdock.docking.event.DockingMonitor;
import org.flexdock.docking.props.DockablePropertySet;
/**
* This interface is designed to specify the API's required by
* {@code DockingManager} and {@code DockingPort} for dealing with dockable
* components in a drag-n-drop fashion. A {@code Dockable} is the child
* component that is docked into a {@code DockingPort}.
*
* @author Christopher Butler
*/
public interface Dockable extends DockingListener, DockingMonitor {
/**
* A constant property key to signify that a component is dockable.
*/
String DOCKABLE_INDICATOR = "Dockable.DOCKABLE_INDICATOR";
/**
* Returns the value of the property with the specified key. Only properties
* added with {@code putClientProperty} will return a non-{@code null}
* value.
*
* @param key
* the key that is being queried
* @return the value of this property or {@code null}
* @see javax.swing.JComponent#getClientProperty(java.lang.Object)
*/
Object getClientProperty(Object key);
/**
* Returns the Component that is to be dragged and docked. This may or may
* not be included in the list returned by {@code getDragSources()}.
*
* The framework performs indexing on the underlying {@code Component}.
* Consequently, this method may not return a {@code null}
* reference.
*
* @return the component wrapped by this dockable.
*/
Component getComponent();
/**
* Returns the DockingPort within which this Dockable is currently docked.
* If not currently docked, this method will return null.
*
* @return the docking port this dockable resides in, or {@code null} if the
* dockable is not currently docked (i.e. in the middle of a drag
* operation).
*/
DockingPort getDockingPort();
/**
* Returns a {@code List} of the {@code Components} that are event sources
* for drag operations. The list may or may not include the Component
* returned by {@code getComponent()}.
*
* @return a list containing the components that may be used to drag this
* dockable.
*/
List getDragSources();
/**
* Returns a {@code Set} of the {@code Components} that are used as frame
* drag sources. When a {@code Dockable} is floated into an external frame,
* that frame may or may not have a titlebar for repositioning. The
* Components returned by this method will be setup with appropriate event
* listeners such that dragging them will serve to reposition the containing
* frame as if they were the frame titlebar. If a Component exists in both
* the Set returned by this method and the List returned by
* {@code getDragSources()}, the "frame reposition" behavior will supercede
* any "drag-to-dock" behavior while the Dockable is in a floating state.
*
* @return a set containing the components that may be used to drag the
* frame this dockable resides in, if the dockable is floating.
*/
Set getFrameDragSources();
/**
* Returns a {@code String} identifier that is unique within a JVM instance,
* but persistent across JVM instances. This is used for configuration
* mangement, allowing the JVM to recognize a {@code Dockable} instance
* within an application instance, persist the ID, and recall it in later
* application instances. The ID should be unique within an appliation
* instance so that there are no collisions with other {@code Dockable}
* instances, but it should also be consistent from JVM to JVM so that the
* association between a {@code Dockable} instance and its ID can be
* remembered from session to session.
*
* The framework performs indexing on the persistent ID. Consequently, this
* method may not return a {@code null} reference.
*
* @return the persistence id for this dockable. This id ensures that only
* one copy of a given dockable will exist.
*/
String getPersistentId();
/**
* Adds an arbitrary key/value "client property" to this {@code Dockable}.
* {@code null} values are allowed.
*
* @param key
* the new client property key.
* @param value
* the new client property value; if null
this
* method will remove the property.
* @see javax.swing.JComponent#putClientProperty(java.lang.Object,
* java.lang.Object)
*/
void putClientProperty(Object key, Object value);
/**
* Returns a {@code DockablePropertySet} instance associated with this
* {@code Dockable}. Developers implementing the {@code Dockable} interface
* may or may not choose to provide their own {@code DockablePropertySet}
* implementation for use with this method. A default implementation is
* supplied by the framework and most {@code Dockable} implementations,
* including all implementations provided by the framework, will return the
* default {@code DockablePropertySet} via a call to
* {@code org.flexdock.docking.props.PropertyManager}. Developers are
* encouraged to take advantage of this by calling
* {@code PropertyManager.getDockablePropertySet(this)}.
*
* @return the {@code DockablePropertySet} associated with this
* {@code Dockable} This method may not return a {@code null}
* reference.
* @see org.flexdock.docking.props.DockablePropertySet
* @see org.flexdock.docking.props.PropertyManager#getDockablePropertySet(Dockable)
*/
DockablePropertySet getDockingProperties();
/**
* Implements the semantics for docking an external {@code Dockable} to this
* {@code Dockable} and returns a {@code boolean} indicating whether or not
* the docking operation was successful.
The framework already
* provides a default implementation for this method through
* {@code DockingManager.dock(Dockable dockable, Dockable parent)}. While
* users are free to provide their own implementation for this method, the
* recommended approach is to use the default implementation with the
* following line:
{@code return DockingManager.dock(dockable, this);}
*
* @param dockable
* the {@code Dockable} to dock relative to this {@code Dockable}
* @return {@code true} if the docking operation was successful;
* {@code false} otherwise.
* @see #dock(Dockable, String)
* @see #dock(Dockable, String, float)
* @see DockingManager#dock(Dockable, Dockable)
*/
boolean dock(Dockable dockable);
/**
* Implements the semantics for docking an external {@code Dockable} to the
* specified region of this {@code Dockable} and returns a {@code boolean}
* indicating whether or not the docking operation was successful. If the
* docking operation results in a split layout, this method should determine
* an appropriate ratio of available space to allot to the new sibling
* {@code Dockable}.
The framework already provides a default
* implementation for this method through
* {@code DockingManager.dock(Dockable dockable, Dockable parent, String region)}.
* While users are free to provide their own implementation for this method,
* the recommended approach is to use the default implementation with the
* following line:
* {@code return DockingManager.dock(dockable, this, relativeRegion);}
*
* @param dockable
* the {@code Dockable} to dock relative to this {@code Dockable}
* @param relativeRegion
* the docking region into which to dock the specified
* {@code Dockable}
* @return {@code true} if the docking operation was successful;
* {@code false} otherwise.
* @see #dock(Dockable, String, float)
* @see DockingManager#dock(Dockable, Dockable, String)
*/
boolean dock(Dockable dockable, String relativeRegion);
/**
* Implements the semantics for docking an external {@code Dockable} to the
* specified region of this {@code Dockable} with the specified layout
* ratio, returning a {@code boolean} indicating whether or not the docking
* operation was successful. If the docking operation results in a split
* layout, this method should use the specified {@code ratio} to determine
* the amount of available space to allot to the new sibling
* {@code Dockable}.
*
* The framework already provides a default implementation for this method
* through
* {@code DockingManager.dock(Dockable dockable, Dockable parent, String region, float proportion)}.
* While users are free to provide their own implementation for this method,
* the recommended approach is to use the default implementation with the
* following line:
*
* {@code return DockingManager.dock(dockable, this, relativeRegion, ratio);}
*
* @param dockable
* the {@code Dockable} to dock relative to this {@code Dockable}
* @param relativeRegion
* the docking region into which to dock the specified
* {@code Dockable}
* @param ratio
* the proportion of available space in the resulting layout to
* allot to the new sibling {@code Dockable}.
* @return {@code true} if the docking operation was successful;
* {@code false} otherwise.
* @see DockingManager#dock(Dockable, Dockable, String, float)
*/
boolean dock(Dockable dockable, String relativeRegion, float ratio);
/**
* Adds a PropertyChangeListener to the listener list. The listener is
* registered for all bound properties of this class. Note that if this
* Dockable is inheriting a bound property, then no event will be fired in
* response to a change in the inherited property.
*
* If listener is null, no exception is thrown and no action is performed.
*
* @param listener
* the PropertyChangeListener to be added
*
* @see #removePropertyChangeListener(PropertyChangeListener)
*/
void addPropertyChangeListener(PropertyChangeListener listener);
/**
* Removes a PropertyChangeListener from the listener list. This method
* should be used to remove PropertyChangeListeners that were registered for
* all bound properties of this class.
*
* If listener is null, no exception is thrown and no action is performed.
*
* @param listener
* the PropertyChangeListener to be removed
*
* @see #addPropertyChangeListener
*/
void removePropertyChangeListener(PropertyChangeListener listener);
}