📄 defaultdockingport.java
字号:
id = UUID.randomUUID().toString();
}
persistentId = id;
DockingPortTracker.updateIndex(this);
}
private String getValidTabTitle(JTabbedPane tabs, Component comp) {
String title = (String) COMPONENT_TITLES.get(comp);
if (title == null || title.trim().length() == 0)
title = "null";
int tc = tabs.getTabCount();
int occurrances = 0;
HashSet titles = new HashSet();
String tmp = null;
for (int i = 0; i < tc; i++) {
tmp = tabs.getTitleAt(i).toLowerCase();
titles.add(tmp);
if (tmp.startsWith(title.toLowerCase()))
occurrances++;
}
if (titles.contains(title) && occurrances > 0)
title += occurrances;
COMPONENT_TITLES.put(comp, title);
return title;
}
/**
* Returns {@code true} if single tabs are allowed within this
* {@code DockingPort}, {@code false} otherwise.
* <p>
* Generally the tabbed interface does not appear until two or more
* {@code Dockables} are docked to the {@code CENTER_REGION} of the
* {@code DockingPort} and tabs are required to switch between them. When
* there is only a single {@code Dockable} within the {@code DockingPort},
* the default behavior for the dockable {@code Component} to take up all of
* the space within the {@code DockingPort}.
* <p>
* If this method returns {@code true}, then a single {@code Dockable}
* within this {@code DockingPort} will reside within a tabbed layout that
* contains only one tab.
* <p>
* The value returned by this method is a scoped property. This means there
* may be many different "scopes" at which the single-tab property may be
* set. For instance, a "global" setting may override the individual setting
* for this {@code DockingPort}, and this {@code DockingPort's} particular
* setting may override the global default setting.
* {@code org.flexdock.docking.props.PropertyManager} should be referenced
* for further information on scoped properties.
*
* @return {@code true} if single tabs are allowed within this
* {@code DockingPort}, {@code false} otherwise.
* @see #setSingleTabAllowed(boolean)
* @see DockingManager#isSingleTabsAllowed()
* @see DockingManager#setSingleTabsAllowed(boolean)
* @see PropertyManager
* @see DockingPortPropertySet#isSingleTabsAllowed()
* @see DockingPortPropertySet#setSingleTabsAllowed(boolean)
*/
public boolean isSingleTabAllowed() {
return getDockingProperties().isSingleTabsAllowed().booleanValue();
}
/**
* Sets the "single tab" property for this {@code DockingPort}, allowing or
* disallowing a single {@code Dockable} within the {@code DockingPort} to
* appear within a tabbed layout.
* <p>
* Generally the tabbed interface does not appear until two or more
* {@code Dockables} are docked to the {@code CENTER_REGION} of the
* {@code DockingPort} and tabs are required to switch between them. When
* there is only a single {@code Dockable} within the {@code DockingPort},
* the default behavior for the dockable {@code Component} to take up all of
* the space within the {@code DockingPort}.
* <p>
* If the single tab property is set to {@code true}, then a single
* {@code Dockable} within this {@code DockingPort} will reside within a
* tabbed layout that contains only one tab.
* <p>
* The single tab property is a scoped property. This means there may be
* many different "scopes" at which the single-tab property may be set. For
* instance, a "global" setting may override the individual setting for this
* {@code DockingPort}, and this {@code DockingPort's} particular setting
* may override the global default setting. <b>This method applied a value
* only to the local scope for this particular {@code DockingPort}.</b>
* {@code org.flexdock.docking.props.PropertyManager} should be referenced
* for further information on scoped properties.
*
* @param allowed
* {@code true} if a single-tabbed layout should be allowed,
* {@code false} otherwise
* @see #isSingleTabAllowed()
* @see DockingManager#setSingleTabsAllowed(boolean)
* @see DockingManager#isSingleTabsAllowed()
* @see PropertyManager
* @see DockingPortPropertySet#setSingleTabsAllowed(boolean)
* @see DockingPortPropertySet#isSingleTabsAllowed()
*/
public void setSingleTabAllowed(boolean allowed) {
getDockingProperties().setSingleTabsAllowed(allowed);
}
/**
* Indicates whether or not the specified component is docked somewhere
* within this {@code DefaultDockingPort}. This method returns {@code true}
* if the specified {@code Component} is a direct child of the
* {@code DefaultDockingPort} or is a direct child of a {@code JTabbedPane}
* or {@code JSplitPane}that is currently the {@code DefaultDockingPort's}docked
* component. Otherwise, this method returns {@code false}. If {@code comp}
* is {@code null}, then then this method return {@code false}
*
* @param comp
* the Component to be tested.
* @return a boolean indicating whether or not the specified component is
* docked somewhere within this {@code DefaultDockingPort}.
* @see DockingPort#isParentDockingPort(java.awt.Component)
* @see Component#getParent()
* @see #getDockedComponent()
*/
public boolean isParentDockingPort(Component comp) {
if (comp == null)
return false;
Container parent = comp.getParent();
// if the component has no parent, then it can't be docked within us
if (parent == null)
return false;
// if we're the direct parent of this component, then we're the parent
// docking port
if (parent == this)
return true;
// if the component is directly inside our docked component, then we're
// also considered its parent dockingPort
return parent == getDockedComponent();
}
protected boolean isValidDockingRegion(String region) {
return DockingManager.isValidDockingRegion(region);
}
private boolean isSingleComponentDocked() {
Component c = getDockedComponent();
// we have no docked component
if (c == null)
return false;
// we do have a docked component. It'll be a splitpane, a tabbedpane,
// or something else.
// if it's a splitpane, then we definitely have more than one component
// docked
if (c instanceof JSplitPane)
return false;
// if it's a tabbed pane, then check the number of tabs on the pane
if (c instanceof JTabbedPane) {
return ((JTabbedPane) c).getTabCount() == 1;
}
// splitpane and tabbed pane are the only two subcontainers that signify
// more than one docked component. if neither, then we only have one
// component docked.
return true;
}
protected Dockable getCenterDockable() {
// can't have a CENTER dockable if there's nothing in the center
if (!isSingleComponentDocked())
return null;
// get the component in the CENTER
Component c = getDockedComponent();
if (c instanceof JTabbedPane) {
// if in a tabbed pane, get the first component in there.
// (there will only be 1, since we've already passed the
// isSingleComponentDocked() test)
c = ((JTabbedPane) c).getComponent(0);
}
// return the Dockable instance associated with this component
return DockingManager.getDockable(c);
}
private DockingPort[] putPortsInOrder(DockingPort oldPort,
DockingPort newPort, String region) {
if (NORTH_REGION.equals(region) || WEST_REGION.equals(region))
return new DockingPort[] { newPort, oldPort };
return new DockingPort[] { oldPort, newPort };
}
/**
* This method completes with a call to
* {@code evaluateDockingBorderStatus()} to allow any installed
* {@code DefaultDockingStrategy} to handle container-state-related
* behavior.
*/
private void reevaluateContainerTree() {
reevaluateDockingWrapper();
reevaluateTabbedPane();
evaluateDockingBorderStatus();
}
private void reevaluateDockingWrapper() {
Component docked = getDockedComponent();
Container parent = getParent();
Container grandParent = parent == null ? null : parent.getParent();
// added grandparent check up here so we will be able to legally embed a
// DefaultDockingPort within a plain JSplitPane without triggering an
// unnecessary remove()
if (docked == null && parent instanceof JSplitPane
&& grandParent instanceof DefaultDockingPort) {
// in this case, the docked component has disappeared (removed) and
// our parent component is a wrapper for us and our child so that we
// can share the root docking port with another component. since our
// child is gone, there's no point in our being here anymore and our
// sibling component shouldn't have to share screen real estate with
// us anymore. we'll remove ourselves and notify the root docking
// port that the component tree has been modified.
parent.remove(this);
((DefaultDockingPort) grandParent).reevaluateContainerTree(); // LABEL
// 1
} else if (docked instanceof JSplitPane) {
// in this case, we're the parent of a docking wrapper. this implies
// that we're splitting our real estate between two components. (in
// practice, we're actually the parent that was called above at
// LABEL
// 1).
JSplitPane wrapper = (JSplitPane) docked;
Component left = wrapper.getLeftComponent();
Component right = wrapper.getRightComponent();
// first, check to make sure we do in fact have 2 components. if so,
// then we don't have
// to go any further.
if (left != null && right != null)
return;
// check to see if we have zero components. if so, remove everything
// and return.
if (left == right) {
removeAll();
return;
}
// if we got here, then one of our components has been removed (i.e.
// LABEL 1). In this
// case, we want to pull the remaining content out of its
// split-wrapper and add it
// as a direct child to ourselves.
Component comp = left == null ? right : left;
wrapper.remove(comp);
// do some cleanup on the wrapper before removing it
if (wrapper instanceof DockingSplitPane) {
((DockingSplitPane) wrapper).cleanup();
}
super.remove(wrapper);
if (comp instanceof DefaultDockingPort)
comp = ((DefaultDockingPort) comp).getDockedComponent();
if (comp != null)
setComponent(comp);
}
}
private void reevaluateTabbedPane() {
Component docked = getDockedComponent();
if (!(docked instanceof JTabbedPane))
return;
JTabbedPane tabs = (JTabbedPane) docked;
int tabCount = tabs.getTabCount();
// we don't have to do anything special here if there is more than the
// minimum number of allowable tabs
int minTabs = isSingleTabAllowed() ? 0 : 1;
if (tabCount > minTabs) {
return;
}
// otherwise, pull out the component in the remaining tab (if it
// exists), and add it to ourselves as a direct child (ditching the
// JTabbedPane).
Component comp = tabCount == 1 ? tabs.getComponentAt(0) : null;
removeAll();
if (comp != null)
setComponent(comp);
Container parent = getParent();
Container grandParent = parent == null ? null : parent.getParent();
// if our TabbedPane's last component was removed, then the TabbedPane
// itself has now been removed. if we're a child port within a
// JSplitPane
// within another DockingPort, then we ourselved need to be removed from
// the component tree, since we don't ha
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -