org.flexdock.docking.defaults
Class DefaultDockingStrategy

java.lang.Object
  extended by org.flexdock.docking.defaults.DefaultDockingStrategy
All Implemented Interfaces:
DockingConstants, DockingStrategy

public class DefaultDockingStrategy
extends Object
implements DockingStrategy, DockingConstants

Author:
Christopher Butler

Nested Class Summary
protected static class DefaultDockingStrategy.DockingResults
           
 
Field Summary
static String PREFERRED_PROPORTION
           
 
Fields inherited from interface org.flexdock.docking.DockingConstants
ACTIVE_WINDOW, BOTTOM, CENTER, CENTER_REGION, CLOSE_ACTION, DEFAULT_PERSISTENCE_KEY, DOCKING_ID, EAST_REGION, HEAVYWEIGHT_DOCKABLES, HORIZONTAL, LEFT, MOUSE_PRESSED, NORTH_REGION, PERMANENT_FOCUS_OWNER, PIN_ACTION, REGION, RIGHT, SOUTH_REGION, TOP, UNINITIALIZED, UNINITIALIZED_RATIO, UNKNOWN_REGION, UNSPECIFIED_SIBLING_PREF, VERTICAL, WEST_REGION
 
Constructor Summary
DefaultDockingStrategy()
           
 
Method Summary
 DockingPort createDockingPort(DockingPort base)
          Returns a new DefaultDockingPort with characteristics similar to the specified base DockingPort.
protected  DockingPort createDockingPortImpl(DockingPort base)
           
 JSplitPane createSplitPane(DockingPort base, String region)
          Returns a new DockingSplitPane based on the specified DockingPort.
protected  JSplitPane createSplitPaneImpl(DockingPort base, String region)
           
 boolean dock(Dockable dockable, DockingPort port, String region)
          Docks the specified Dockable into the supplied region of the specified DockingPort.
 boolean dock(Dockable dockable, DockingPort port, String region, DragOperation operation)
          Docks the specified Dockable into the supplied region of the specified DockingPort.
protected  boolean dragThresholdElapsed(DragOperation token)
           
protected  DefaultDockingStrategy.DockingResults dropComponent(Dockable dockable, DockingPort target, String region, DragOperation token)
           
static String findRegion(Component comp)
          Returns the docking region within the current split docking layout containing the specified Component.
protected  DefaultDockingStrategy.DockingResults floatComponent(Dockable dockable, DockingPort target, DragOperation token)
           
protected  String getCreationRegion(JSplitPane splitPane)
           
 double getDividerProportion(DockingPort port, JSplitPane splitPane)
          Returns the desired divider proportion of the specified JSplitPane after rendering.
protected  Component getElderComponent(JSplitPane splitPane)
           
 int getInitialDividerLocation(DockingPort port, JSplitPane splitPane)
          Returns the initial divider location to be used by the specified JSplitPane when it is embedded within the specified DockingPort.
protected static Float getPreferredProportion(Component c)
           
protected  Float getPreferredProportion(JSplitPane splitPane, Component controller)
           
static Dockable getSibling(Dockable dockable)
          Returns the specified Dockable's sibling Dockable within the current docking layout.
static Dockable getSibling(Dockable dockable, String region)
          Returns the sibling Dockable relative to the specified Dockable's supplied region in the current docking layout.
protected  boolean isDockingPossible(Dockable dockable, DockingPort port, String region, DragOperation token)
           
protected  boolean isElderTopLeft(JSplitPane splitPane)
           
protected  boolean isFloatable(Dockable dockable, DragOperation token)
           
static void setDefaultResizeWeight(double rw)
           
 boolean undock(Dockable dockable)
          Undocks the specified Dockable from it's parent DockingPort.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

PREFERRED_PROPORTION

public static final String PREFERRED_PROPORTION
See Also:
Constant Field Values
Constructor Detail

DefaultDockingStrategy

public DefaultDockingStrategy()
Method Detail

getSibling

public static Dockable getSibling(Dockable dockable)
Returns the specified Dockable's sibling Dockable within the current docking layout. This method checks the parent DockingPort of a given Dockable to see if it is split equally with another Dockable. If so, the immediate sibling Dockable is returned. If there are more than two Dockables within the split layout, then the closest sibling region is determined and this method dispatches to getSibling(Dockable dockable, String region).

If the specified Dockable is null, or there are no siblings available in the docking layout, then this methdo returns a null reference. If the specified Dockable is not currently docked within a DockingPort, then this method returns a null reference.

Parameters:
dockable - the Dockable whose sibling is to be returned
Returns:
the sibling of the specified Dockable within the current docking layout.
See Also:
Dockable.getDockingPort(), getSibling(Dockable, String)

getSibling

public static Dockable getSibling(Dockable dockable,
                                  String region)
Returns the sibling Dockable relative to the specified Dockable's supplied region in the current docking layout. If dockable is null or region is either invalid or equal to CENTER_REGION, then this method returns a null reference.

If the specified Dockable is in a DockingPort that equally splits the layout between two Dockables in a fashion that matches up with the specified region, then the immediate sibling Dockable is returned. Otherwise, a fuzzy search is performed throughout the docking layout for a Dockable that "looks like" it is docked to the supplied region of the specified Dockable from a visual standpoint.

For instance, a docking layout may consist of four quadrants Dockable1 (top-left), Dockable2 (top-right), Dockable3 (bottom-left) and Dockable4 (bottom-right). The layout is built by docking Dockable2>/i> to the EAST_REGION of Dockable1, Dockable3 to the SOUTH_REGION of Dockable1, and Dockable4 to the SOUTH_REGION of Dockable2. Within this layout, Dockable1 and Dockable3 are immediate siblings, as are Dockable2 and Dockable4. Thus, requesting sibling NORTH_REGION of Dockable3 will easily yield Dockable1. However, Dockable3 has no immediate EAST_REGION sibling. In this case, a fuzzy search through the layout is performed to determine the visual sibling, and this method returns Dockable4. Likewise, this method will return a null reference for the WEST_REGION sibling of Dockable3}, since there are no Dockables in the visual layout to the west of this Dockable.

Parameters:
dockable - the Dockable whose sibling is to be returned
region - the region of the specified Dockable whose visual sibling is to be returned
Returns:
the Dockable in the supplied region relative to the specified Dockable

findRegion

public static String findRegion(Component comp)
Returns the docking region within the current split docking layout containing the specified Component. If comp is null, then a null reference is returned. If comp is not in a split layout, then CENTER_REGION is returned.

This method resolves the associated Dockable and DockingPort for the specified Component and backtracks through the docking layout to find a split layout. If a split layout is found, then the region retured by this method is calculated relative to its sibling in the layout.

Parameters:
comp - the Component whose region is to be returned
Returns:
the region of the current split layout containing the specified Dockable

dock

public boolean dock(Dockable dockable,
                    DockingPort port,
                    String region)
Docks the specified Dockable into the supplied region of the specified DockingPort. This method is meant for programmatic docking, as opposed to realtime, event-based docking operations. As such, it defers processing to dock(Dockable dockable, DockingPort port, String region, DragOperation token), passing a null argument for the DragOperation parameter. This implies that there is no event-based drag operation currently in progress to control the semantics of the docking operation, only that an attempt should be made to dock the specified Dockable into the specified DockingPort.

This method will return false if dockable or port are null, or if region is not a valid region according to the specified DockingPort. If a Dockable is currently docked within the specified DockingPort, then that Dockable's territorial properties are also checked and this method may return false if the territory is blocked. Finally, this method will return false if the specified Dockable is already docked within the supplied region of the specified

Specified by:
dock in interface DockingStrategy
Parameters:
dockable - the Dockable we wish to dock
port - the DockingPort into which we wish to dock
region - the region of the specified DockingPort into which we wish to dock.
Returns:
true if the docking operation was successful, false. otherwise.
See Also:
dock(Dockable, DockingPort, String, DragOperation), Dockable.getDockingProperties(), DockablePropertySet.isTerritoryBlocked(String)

dock

public boolean dock(Dockable dockable,
                    DockingPort port,
                    String region,
                    DragOperation operation)
Docks the specified Dockable into the supplied region of the specified DockingPort. This method is meant for realtime, event-based docking based on an in-progress drag operation. It is not recommended for developers to call this method programmatically, except to pass in a null DragOperation argument. *

The DragOperation parameter, if present, will control the semantics of the docking operation based upon current mouse position, drag threshold, and a customizable drag context Map. For instance, the DragOperation may contain information regarding the Dockable over which the mouse is currently hovered, whether the user is attempting to drag a Dockable outside the bounds of any existing windows (perhaps in an attempt to float the Dockable), or whether the current distance offset from the original drag point sufficiently warrants a valid docking operation.

If the DragOperation is null, then this method will attempt to programmatically dock the specified Dockable into the supplied region of the specified DockingPort without regard to external event-based criteria. This is in accordance with the behavior specified by dock(Dockable dockable, DockingPort port, String region). This method will return false if dockable or port are null, or if region is not a valid region according to the specified DockingPort. If a Dockable is currently docked within the specified DockingPort, then that Dockable's territorial properties are also checked and this method may return false if the territory is blocked. If a DragOperation is present, then this method will return false if the required drag threshold has not been exceeded. Finally, this method will return false if the specified Dockable is already docked within the supplied region of the specified

Specified by:
dock in interface DockingStrategy
Parameters:
dockable - the Dockable we wish to dock
port - the DockingPort into which we wish to dock
region - the region of the specified DockingPort into which we wish to dock.
operation - the DragOperation describing the state of the application/mouse at the point in time in which we're attempting to dock.
Returns:
true if the docking operation was successful, false. otherwise.
See Also:
dock(Dockable, DockingPort, String, DragOperation), Dockable.getDockingProperties(), DockablePropertySet.isTerritoryBlocked(String)

dragThresholdElapsed

protected boolean dragThresholdElapsed(DragOperation token)

isDockingPossible

protected boolean isDockingPossible(Dockable dockable,
                                    DockingPort port,
                                    String region,
                                    DragOperation token)

isFloatable

protected boolean isFloatable(Dockable dockable,
                              DragOperation token)

dropComponent

protected DefaultDockingStrategy.DockingResults dropComponent(Dockable dockable,
                                                              DockingPort target,
                                                              String region,
                                                              DragOperation token)

undock

public boolean undock(Dockable dockable)
Undocks the specified Dockable from it's parent DockingPort. If dockable is null or is not currently docked within a DockingPort, then this method returns false.

Specified by:
undock in interface DockingStrategy
Parameters:
dockable - the Dockable to be undocked.
Returns:
true if the undocking operation was successful, false otherwise.
See Also:
dock(Dockable, DockingPort, String)

floatComponent

protected DefaultDockingStrategy.DockingResults floatComponent(Dockable dockable,
                                                               DockingPort target,
                                                               DragOperation token)

createDockingPort

public DockingPort createDockingPort(DockingPort base)
Returns a new DefaultDockingPort with characteristics similar to the specified base DockingPort. If the base DockingPort is a DefaultDockingPort, then the returned DockingPort will share the base DockingPort's border manager and tabbed drag-source flag. The returned DockingPort's isRoot() method will return false.

Specified by:
createDockingPort in interface DockingStrategy
Parameters:
base - the DockingPort off of which to base the returned DockingPort
Returns:
a new DefaultDockingPort with characteristics similar to the specified base DockingPort.
See Also:
DefaultDockingPort.getBorderManager(), DefaultDockingPort.setBorderManager(BorderManager), DefaultDockingPort.isTabsAsDragSource(), DefaultDockingPort.setTabsAsDragSource(boolean), DefaultDockingPort.setRoot(boolean)

createDockingPortImpl

protected DockingPort createDockingPortImpl(DockingPort base)

createSplitPane

public JSplitPane createSplitPane(DockingPort base,
                                  String region)
Returns a new DockingSplitPane based on the specified DockingPort. and region. Creation of the DockingSplitPane is deferred to an internal protected method to allow for overriding by subclasses. A client property is set on the returned split pane with the key DockingConstants.REGION to indicate the creation region of the split pane for non-DockingSplitPanes returned by overriding subclasses.

This method determines the "elder" component of the split pane by checking whether the new creation region is in the TOP or LEFT (NORTH_REGION or WEST_REGION). If the creation region, representing where the new Dockable will be docked, is not in the top or left, then the elder Component in the split pane must be. This information is used to initialize the resize weight of the split pane, setting resize weight to 1 if the elder is in the top or left of the split pane and 0 if not. This gives the elder Component in the resulting split pane priority in the layout with resizing the split pane.

If the creation region is NORTH_REGION or SOUTH_REGION, the returned split pane is initialized with a VERTICAL_SPLIT orientation; otherwise a HORIZONTAL_SPLIT orientation is used.

Before returning, the border is removed from the split pane, its divider size is set to 3, and if possible the border is removed from the split pane divider. This is to avoid an excessive compound border effect for embedded Components within the split pane that may have their own borders.

Specified by:
createSplitPane in interface DockingStrategy
Parameters:
base - the DockingPort off of which the returned JSplitPane will be based.
region - the region within the base DockingPort used to determine the orientation of the returned JSplitPane.
Returns:
a new DockingSplitPane based on the specified DockingPort. and region.
See Also:
DockingSplitPane.DockingSplitPane(DockingPort, String), createSplitPaneImpl(DockingPort, String), JSplitPane.setResizeWeight(double)

createSplitPaneImpl

protected JSplitPane createSplitPaneImpl(DockingPort base,
                                         String region)

getInitialDividerLocation

public int getInitialDividerLocation(DockingPort port,
                                     JSplitPane splitPane)
Returns the initial divider location to be used by the specified JSplitPane when it is embedded within the specified DockingPort. It is assumed that the JSplitPane parameter is embedded within the specified DockingPort, is validated, visible, and its dimensions are non-zero.

This method gets the "size" of the specified DockingPort based on the orientation of the split pane (width for horizontal split, height for vertical split) minus the DockingPort's insets. It then dispatches to getDividerProportion(DockingPort port, JSplitPane splitPane) to determine the preferred proportion of the split pane divider. The returned value for this method is the product of the DockingPort size and the split proportion.

If either port or splitPane parameters are null, then this method returns 0.

Specified by:
getInitialDividerLocation in interface DockingStrategy
Parameters:
port - the DockingPort that contains the specified JSplitPane.
splitPane - the JSplitPane whose initial divider location is to be determined.
Returns:
the desired divider location of the supplied JSplitPane.
See Also:
DockingStrategy.getInitialDividerLocation(DockingPort, JSplitPane), getDividerProportion(DockingPort, JSplitPane)

getDividerProportion

public double getDividerProportion(DockingPort port,
                                   JSplitPane splitPane)
Returns the desired divider proportion of the specified JSplitPane after rendering. This method assumes that the JSplitPane parameter is, or will be embedded within the specified DockingPort. This method does not assume that the JSplitPane has been validated and that it's current dimensions are non-zero.

If either port or splitPane parameters are null, then this method returns the default value of RegionChecker.DEFAULT_SIBLING_SIZE. Otherwise the "elder" component within the JSplitPane is determined to see if it is contained within a sub-DockingPort. If the "elder" Component cannot be determined, or it is not contained within a sub-DockingPort, then the default value of RegionChecker.DEFAULT_SIBLING_SIZE is returned.

If the "elder" Component is successfully resolved inside a sub-DockingPort, then a check is done on the sub-port for the client property DefaultDockingStrategy.PREFERRED_PROPORTION. If this value is found, then the primitive float version of it is returned.

Failing these checks, the Dockable is resolved for the "elder" Component in the specified JSplitPane via DockingManager.getDockable(Component comp). If no Dockable can be found, then RegionChecker.DEFAULT_SIBLING_SIZE is returned.

Otherwise, the DockingPortPropertySet is retrieved from the specified DockingPort and its getRegionChecker() method is called. getSiblingSize(Component c, String region) is invoked on the returned RegionChecker passing the "elder" Component in the split pane and the creation region resolved for the specified JSplitPane. This resolves the preferred sibling size for the elder Dockable component. If the elder Component is in the top/left of the split pane, then 1F-prefSize is returned. Otherwise, the preferred sibling size is returned.

Specified by:
getDividerProportion in interface DockingStrategy
Parameters:
port - the DockingPort that contains, or will contain the specified JSplitPane.
splitPane - the JSplitPane whose initial divider location is to be determined.
Returns:
the desired divider proportion of the supplied JSplitPane.
See Also:
RegionChecker.DEFAULT_SIBLING_SIZE, PREFERRED_PROPORTION, DockingManager.getDockable(Component), RegionChecker.getSiblingSize(Component, String)

getCreationRegion

protected String getCreationRegion(JSplitPane splitPane)

isElderTopLeft

protected boolean isElderTopLeft(JSplitPane splitPane)

getPreferredProportion

protected Float getPreferredProportion(JSplitPane splitPane,
                                       Component controller)

getElderComponent

protected Component getElderComponent(JSplitPane splitPane)

getPreferredProportion

protected static Float getPreferredProportion(Component c)

setDefaultResizeWeight

public static void setDefaultResizeWeight(double rw)