/* * 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 javax.swing.JSplitPane; import org.flexdock.docking.drag.DragOperation; /** * This interface defines an API used by {@code DockingManager} and * {@code DockingPort} to support customizable behaviors during docking * operations. {@code DockingManager} will associate a {@code DockingStrategy} * with a particular {@code DockingPort} or {@code Dockable} class type. Calls * to {@code DockingManager.dock()} and {@code DockingManager.undock()} will be * deferred to the {@code DockingStrategy} associated with the parameters * supplied in the respective method calls. {@code DockingStrategies} are also * responsible for creating sub-DockingPorts and split panes for nested * {@code DockingPorts} * * Implementations of {@code DockingStrategy} are responsible for managing * component relationships between {@code Dockables} and parent containers. This * includes making determinations as to whether a particular docking operation * will be allowed for the specified parameters and the specifics of how a * particular {@code Dockable} may be removed from one parent * {@code Container} or {@code DockingPort} and added to another. * {@code DockingStrategy} may determine whether a call to {@code dock()} * implies an attempt to float a {@code Dockable} in a separate window. * * Because of the potentially large scope of responsibilities associated with a * {@code DockingStrategy}, implementations may range from being very simple to * highly complex. Although custom implementations of {@code DockingStrategy} * are not discouraged, the recommeded path is to subclass * {@code DefaultDockingStrategy} for consistency of behavior. * * {@code DockingStrategies} are associated with a particular type of * {@code Dockable} or {@code DockingPort} by calling * {@code DockingManager.setDockingStrategy(Class c, DockingStrategy strategy)}. * {@code DefaultDockingStrategy} is the default implementation used for all * classes that do not have a custom {@code DockingStrategy} registered. * * @author Christopher Butler */ public interface DockingStrategy { /** * Attempts to dock the specified {@code Dockable} into the supplied * {@code DockingPort} in the specified region. If docking is not possible * for the specified parameters, then the method returns {@code false} and * no action is taken. Since there is no {@code DragOperation} parameter * present, this method implies programmatic docking as opposed to docking * as a result of drag-events. * * @param dockable * the {@code Dockable} we wish to dock * @param dockingPort * the {@code DockingPort} into which we wish to dock * @param dockingRegion * the region of the specified {@code DockingPort} into which we * wish to dock. * @return whether or not the docking operation was successful. */ boolean dock(Dockable dockable, DockingPort dockingPort, String dockingRegion); /** * Attempts to dock the specified {@code Dockable} into the supplied * {@code DockingPort} in the specified region based upon the semantics of * the specified {@code DragOperation}. If docking is not possible * for the specified parameters, then the method returns {@code false} and * no action is taken. * * @param dockable * the {@code Dockable} we wish to dock * @param dockingPort * the {@code DockingPort} into which we wish to dock * @param dockingRegion * the region of the specified {@code DockingPort} into which we * wish to dock. * @param operation * the {@code DragOperation} describing the state of the * application/mouse at the point in time in which we're * attempting to dock. * @return whether or not the docking operation was successful. */ boolean dock(Dockable dockable, DockingPort dockingPort, String dockingRegion, DragOperation operation); /** * Undocks the specified {@code Dockable} instance from its containing * {@code DockingPort}. * * @param dockable * the {@code Dockable} we wish to undock * @return {@code true} if the {@code Dockable} was successfully undocked. * Otherwise, returns {@code false}. */ boolean undock(Dockable dockable); /** * Creates and returns a new {@code DockingPort} instance based upon the * supplied {@code DockingPort} parameter. For layouts that support nested * {@code DockingPorts}, this method is useful for creating child * {@code DockingPorts} suitable for embedding within the base * {@code DockingPort} * * @param base * the {@code DockingPort} off of which the returned instance * will be based. * @return a new {@code DockingPort} instance based upon the supplied * parameter. */ DockingPort createDockingPort(DockingPort base); /** * Creates and returns a new {@code JSplitPane} instance based upon the * supplied parameters. The returned {@code JSplitPane} should be suitable * for embedding within the base {@code DockingPort} and its orientation * should reflect the supplied {@code region} parameter. * * @param base * the {@code DockingPort} off of which the returned * {@code JSplitPane} will be based. * @param region * the region within the base {@code DockingPort} used to * determine the orientation of the returned {@code JSplitPane}. * @return a new {@code JSplitPane} suitable for embedding within the base * {@code DockingPort} parameter. */ JSplitPane createSplitPane(DockingPort base, String region); /** * Creates and returns a new {@code JSplitPane} instance based upon the * supplied parameters. The returned {@code JSplitPane} should be suitable * for embedding within the base {@code DockingPort} and its orientation * should reflect the supplied {@code region} parameter. * * @param base * the {@code DockingPort} off of which the returned * {@code JSplitPane} will be based. * @param region * the region within the base {@code DockingPort} used to * determine the orientation of the returned {@code JSplitPane}. * @param percent * the percentage used in the split. * @return a new {@code JSplitPane} suitable for embedding within the base * {@code DockingPort} parameter. */ JSplitPane createSplitPane(DockingPort base, String region, float percent); /** * Returns the initial divider location to be used by the specified * {@code JSplitPane}. This method assumes that the {@code JSplitPane} * parameter is embedded within the specified {@code DockingPort} and that * is has been validated and its current dimensions are non-zero. * * @param dockingPort * the {@code DockingPort} that contains, or will contain the * specified {@code JSplitPane}. * @param splitPane * the {@code JSplitPane} whose initial divider location is to be * determined. * @return the desired divider location of the supplied {@code JSplitPane}. */ int getInitialDividerLocation(DockingPort dockingPort, JSplitPane splitPane); /** * Returns the desired divider proportion of the specified * {@code JSplitPane} after rendering. This method assumes that the * {@code JSplitPane} parameter is, or will be embedded within the specified * {@code DockingPort}. This method does <b>not</b> assume that the * {@code JSplitPane} has been validated and that it's current dimensions * are non-zero. * * @param dockingPort * the {@code DockingPort} that contains, or will contain the * specified {@code JSplitPane}. * @param splitPane * the {@code JSplitPane} whose initial divider location is to be * determined. * @return the desired divider proportion of the supplied {@code JSplitPane}. */ double getDividerProportion(DockingPort dockingPort, JSplitPane splitPane); }