📄 defaultdockingport.java
字号:
if (location == null)
return null;
Component docked = getDockedComponent();
if (docked == null || docked instanceof JSplitPane)
return null;
if (docked instanceof JTabbedPane) {
JTabbedPane tabs = (JTabbedPane) docked;
Component c = tabs.getComponentAt(location.x, location.y);
return c instanceof Dockable ? (Dockable) c : DockingManager
.getDockable(c);
}
return DockingManager.getDockable(docked);
}
/**
* Returns the {@code Component} currently docked within the specified
* {@code region}.
* <p>
* If this {@code DockingPort} has either a single child {@code Dockable} or
* a tabbed layout, then the supplied region must be {@code CENTER_REGION}
* or this method will return a {@code null} reference. If there is a single
* child {@code Dockable}, then this method will return the same
* {@code Component} as returned by {@code getDockedComponent()}. If there
* is a tabbed layout, then this method will return the {@code Component} in
* the currently selected tab.
* <p>
* If this {@code DockingPort} has a split layout, then a check for
* {@code CENTER_REGION} will return a {@code null} reference. For outer
* regions ({@code NORTH_REGION}, {@code SOUTH_REGION},
* {@code EAST_REGION}, or {@code WEST_REGION}), the supplied region
* parameter must match the orientation of the embedded {@code JSplitPane}.
* Thus for a vertically oriented split pane, checks for {@code EAST_REGION}
* and {@code WEST_REGION} will return a {@code null} reference. Likewise,
* for a horizontally oriented split pane, checks for {@code NORTH_REGION}
* and {@code SOUTH_REGION} will return a {@code null} reference.
* <p>
* Outer regions are mapped to corresponding split pane regions.
* {@code NORTH_REGION} maps to the split pane's top component,
* {@code SOUTH_REGION} maps to the bottom, {@code EAST_REGION} maps to the
* right, and {@code WEST_REGION} maps to the left. The sub-{@code DockingPort}
* for the split pane region that corresponds to the specified
* {@code region} parameter will be resolved and this method will return
* that {@code Component} retrieved by calling its
* {@code getDockedComponent()} method. <i>Note that the
* {@code getDockedComponent()} call to a sub- {@code DockingPort} implies
* that the {@code JTabbedPane} or {@code JSplitPane} for the sub-port may
* be returned if the sub-port contains multiple {@code Dockables}.</i>
* <p>
* If this {@code DockingPort} is empty, then this method returns a
* {@code null} reference.
*
* @param region
* the region to be checked for a docked {@code Component}
* @return the {@code Component} docked within the specified region.
* @see DockingPort#getComponent(String)
* @see #getDockedComponent()
*/
public Component getComponent(String region) {
Component docked = getDockedComponent();
if (docked == null)
return null;
if (docked instanceof JTabbedPane) {
// they can only get tabbed dockables if they were checking the
// CENTER region.
if (!CENTER_REGION.equals(region))
return null;
JTabbedPane tabs = (JTabbedPane) docked;
return tabs.getSelectedComponent();
}
if (docked instanceof JSplitPane) {
// they can only get split dockables if they were checking an outer
// region.
if (CENTER_REGION.equals(region))
return null;
JSplitPane split = (JSplitPane) docked;
// make sure the supplied regions correspond to the current
// splitpane orientation
boolean horizontal = split.getOrientation() == JSplitPane.HORIZONTAL_SPLIT;
if (horizontal) {
if (NORTH_REGION.equals(region) || SOUTH_REGION.equals(region))
return null;
} else {
if (EAST_REGION.equals(region) || WEST_REGION.equals(region))
return null;
}
boolean left = NORTH_REGION.equals(region)
|| WEST_REGION.equals(region);
Component c = left ? split.getLeftComponent() : split
.getRightComponent();
// split panes only contain sub-dockingports. if 'c' is not a
// sub-dockingport,
// then something is really screwed up.
if (!(c instanceof DockingPort))
return null;
// get the dockable contained in the sub-dockingport
return ((DockingPort) c).getDockedComponent();
}
// we already checked the tabbed layout and split layout. all that's
// left is the direct-child component itself. this will only ever
// exist in the CENTER, so return it if they requested the CENTER
// region.
return CENTER_REGION.equals(region) ? docked : null;
}
/**
* Returns the {@code Dockable} currently docked within the specified
* {@code region}. This method dispatches to
* {@code getComponent(String region)} to retrieve the {@code Component}
* docked within the specified region and returns its associated
* {@code Dockable} via {@code DockingManager.getDockable(Component comp)}.
* <p>
* There are somewhat strict semantics associated with retrieving the
* {@code Component} in a particular docking region. API documentation for
* {@code getComponent(String region)} should be referenced for a listing of
* the rule set. If {@code region} is invalid according to
* {@code DockingManager.isValidDockingRegion(String region)}, then this
* method returns a {@code null} reference.
*
* @param region
* the region to be checked for a docked {@code Dockable}
* @return the {@code Dockable} docked within the specified region.
* @see DockingPort#getDockable(String)
* @see #getComponent(String)
* @see #getDockedComponent()
* @see DockingManager#getDockable(Component)
* @see DockingManager#isValidDockingRegion(String)
*/
public Dockable getDockable(String region) {
Component c = getComponent(region);
return DockingManager.getDockable(c);
}
/**
* If this method returns {@code null}, implementations may throw
* NullPointerExceptions. Do not expect NPE checking.
*
* @return a valid JTabbedPane.
*/
protected JTabbedPane createTabbedPane() {
Insets oldInsets = UIManager
.getInsets(LookAndFeelSettings.TAB_PANE_BORDER_INSETS);
int tabPlacement = getInitTabPlacement();
int edgeInset = LookAndFeelSettings.getTabEdgeInset(tabPlacement);
Insets newInsets = new Insets(0, 0, 0, 0);
switch (tabPlacement) {
case JTabbedPane.TOP:
newInsets.top = edgeInset >= 0 ? edgeInset : oldInsets.top;
break;
case JTabbedPane.LEFT:
newInsets.left = edgeInset >= 0 ? edgeInset : oldInsets.left;
break;
case JTabbedPane.BOTTOM:
newInsets.bottom = edgeInset >= 0 ? edgeInset : oldInsets.bottom;
break;
case JTabbedPane.RIGHT:
newInsets.right = edgeInset >= 0 ? edgeInset : oldInsets.right;
break;
}
UIManager.put(LookAndFeelSettings.TAB_PANE_BORDER_INSETS, newInsets);
JTabbedPane pane = new JTabbedPane();
pane.setTabPlacement(tabPlacement);
UIManager.put(LookAndFeelSettings.TAB_PANE_BORDER_INSETS, oldInsets);
TabbedDragListener tdl = new TabbedDragListener();
pane.addMouseListener(tdl);
pane.addMouseMotionListener(tdl);
return pane;
}
protected void updateTab(Dockable dockable) {
Component docked = getDockedComponent();
if (docked instanceof JTabbedPane) {
JTabbedPane tabs = (JTabbedPane) docked;
int index = tabs.indexOfComponent(dockable.getComponent());
if (index > -1) {
tabs.setIconAt(index, dockable.getDockingProperties()
.getTabIcon());
tabs.setTitleAt(index, dockable.getDockingProperties()
.getDockableDesc());
}
}
}
/**
* Returns the {@code DockingStrategy} used by this {@code DockingPort}.
* This method dispatches to {@code getDockingStrategy(Object obj)},
* passing {@code this} as an argument. By default,
* {@code DefaultDockingStrategy} is used unless a different
* {@code DockingStrategy} has been assigned by the end user for
* {@code DefaultDockingPort}.
*
* @return the {@code DockingStrategy} used by this {@code DockingPort}.
* @see DockingPort#getDockingStrategy()
* @see DockingManager#getDockingStrategy(Object)
*/
public DockingStrategy getDockingStrategy() {
return DockingManager.getDockingStrategy(this);
}
/**
* Removes all {@code Dockables} from this {@code DockingPort}. Internally,
* this method dispatches to {@code removeAll()}. This ensures that not
* only docked {@code Components} are removed, that that all wrapper
* containers such as {@code JTabbedPanes}, {@code JSplitPanes}, and sub-{@code DockingPorts}
* are removed as well.
*
* @see DockingPort#clear()
* @see #removeAll()
*/
public void clear() {
removeAll();
}
/**
* Docks the specified component within the specified region. This method
* attempts to resolve the {@code Dockable} associated with the specified
* {@code Component} by invoking
* {@code DockingManager.getDockable(Component comp)}. Processing is then
* dispatched to {@code dock(Dockable dockable, String region)}.
* <p>
* If no {@code Dockable} is resolved for the specified {@code Component},
* then this method attempts to register the {@code Component} as a
* {@code Dockable} automatically by calling
* {@code DockingManager.registerDockable(Component comp)}.
* <p>
* If either {@code comp} or {@code region} region are {@code null}, then
* this method returns {@code false}. Otherwise, this method returns a
* boolean indicating the success of the docking operation based upon
* {@code dock(Dockable dockable, String region)}.
*
* @param comp
* the {@code Component} to be docked within this
* {@code DockingPort}
* @param region
* the region within this {@code DockingPort} to dock the
* specified {@code Component}
* @return {@code true} if the docking operation was successful,
* {@code false} otherwise.
* @see DockingPort#dock(Component, String)
* @see #dock(Dockable, String)
* @see DockingManager#getDockable(Component)
* @see DockingManager#registerDockable(Component)
*/
public boolean dock(Component comp, String region) {
if (comp == null || region == null)
return false;
Dockable dockable = DockingManager.getDockable(comp);
if (dockable == null)
dockable = DockingManager.registerDockable(comp);
return dock(dockable, region);
}
/**
* Docks the specified {@code Dockable} within the specified region. The
* {@code Component} used for docking is returned by calling
* {@code getComponent()} on the specified {@code Dockable}. This method
* returns {@code false} immediately if the specified {@code Dockable} is
* {@code null} or if
* {@code isDockingAllowed(Component comp, String region)} returns
* {@code false}.
* <p>
* If this {@code DockingPort} is currently empty, then the {@code Dockable}
* is docked into the {@code CENTER_REGION}, regardless of the supplied
* {@code region} parameter's value.
* <p>
* If {@code isSingleTabAllowed()} returns {@code false} and the
* {@code DockingPort} is emtpy, then the {@code Dockable} will be added
* directly to the {@code DockingPort} and will take up all available space
* within the {@code DockingPort}. In this case, subsequent calls to
* {@code getDockedComponent()} will return the dockable {@code Component}.
* <p>
* If {@code isSingleTabAllowed()} returns {@code true} and the
* {@code DockingPort} is emtpy, then a {@code JTabbedPane} will be added
* directly to the {@code DockingPort} and will take up all available space
* within the {@code DockingPort}. The dockable {@code Component} will be
* added as a tab within the tabbed pane. In this case, subsequent calls to
* {@code getDockedComponent()} will return the {@code JTabbedPane}.
* <p>
* If the {@code DockingPort} is <b>not</b> empty, and the specified region
* is {@code CENTER_REGION}, then the dockable {@code Component} will be
* added to the {@code JTabbedPane} returned by {@code getDockedComponent()}.
* If this {@code DockingPort} only contained a single dockable
* {@code Component} without a tabbed pane, then the currently docked
* {@code Component} is removed, a {@code JTabbedPane} is created and added,
* and both the old {@code Component} and the new one are added to the
* {@code JTabbedPane}. In this case, subsequent calls to
* {@code getDockedComponent()} will return the {@code JTabbedPane}.
* <p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -