![JAR search and dependency download from the Maven repository](/logo.png)
bibliothek.gui.dock.common.CControl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of docking-frames-common Show documentation
Show all versions of docking-frames-common Show documentation
DockingFrames is an open source Java Swing docking framework, licenced under LGPL 2.1.
This is the same distribution as the original distribution (http://www.docking-frames.org/), only reinstalled in maven
/* * Bibliothek - DockingFrames * Library built on Java/Swing, allows the user to "drag and drop" * panels containing any Swing-Component the developer likes to add. * * Copyright (C) 2007 Benjamin Sigg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Benjamin Sigg * [email protected] * CH - Switzerland */ package bibliothek.gui.dock.common; import java.awt.Component; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; import java.util.Set; import javax.swing.FocusManager; import javax.swing.Icon; import javax.swing.JFrame; import javax.swing.KeyStroke; import bibliothek.extension.gui.dock.preference.PreferenceModel; import bibliothek.extension.gui.dock.preference.PreferenceStorage; import bibliothek.extension.gui.dock.theme.BubbleTheme; import bibliothek.extension.gui.dock.theme.EclipseTheme; import bibliothek.extension.gui.dock.theme.FlatTheme; import bibliothek.gui.DockController; import bibliothek.gui.DockFrontend; import bibliothek.gui.DockStation; import bibliothek.gui.DockTheme; import bibliothek.gui.Dockable; import bibliothek.gui.dock.DockElement; import bibliothek.gui.dock.DockFactory; import bibliothek.gui.dock.FlapDockStation; import bibliothek.gui.dock.ScreenDockStation; import bibliothek.gui.dock.SplitDockStation; import bibliothek.gui.dock.StackDockStation; import bibliothek.gui.dock.action.DockAction; import bibliothek.gui.dock.common.action.CloseActionFactory; import bibliothek.gui.dock.common.action.util.CDefaultDockActionDistributor; import bibliothek.gui.dock.common.event.CControlListener; import bibliothek.gui.dock.common.event.CDockableAdapter; import bibliothek.gui.dock.common.event.CDockablePropertyListener; import bibliothek.gui.dock.common.event.CDockableStateListener; import bibliothek.gui.dock.common.event.CDoubleClickListener; import bibliothek.gui.dock.common.event.CFocusListener; import bibliothek.gui.dock.common.event.CKeyboardListener; import bibliothek.gui.dock.common.event.CVetoClosingListener; import bibliothek.gui.dock.common.event.CVetoFocusListener; import bibliothek.gui.dock.common.event.ResizeRequestListener; import bibliothek.gui.dock.common.group.CGroupBehavior; import bibliothek.gui.dock.common.grouping.CGroupingBehavior; import bibliothek.gui.dock.common.grouping.DefaultCGroupingBehavior; import bibliothek.gui.dock.common.grouping.DockableGrouping; import bibliothek.gui.dock.common.grouping.GroupingDockLocationListener; import bibliothek.gui.dock.common.grouping.GroupingHistoryRewriter; import bibliothek.gui.dock.common.intern.CControlAccess; import bibliothek.gui.dock.common.intern.CControlFactory; import bibliothek.gui.dock.common.intern.CDockFrontend; import bibliothek.gui.dock.common.intern.CDockable; import bibliothek.gui.dock.common.intern.CDockableAccess; import bibliothek.gui.dock.common.intern.CListenerCollection; import bibliothek.gui.dock.common.intern.CPlaceholderStrategy; import bibliothek.gui.dock.common.intern.CancelDragAndDropOperation; import bibliothek.gui.dock.common.intern.CommonDockable; import bibliothek.gui.dock.common.intern.CommonMultipleDockableFactory; import bibliothek.gui.dock.common.intern.CommonMultipleDockableLayout; import bibliothek.gui.dock.common.intern.CommonSingleDockableFactory; import bibliothek.gui.dock.common.intern.ControlVetoClosingListener; import bibliothek.gui.dock.common.intern.ControlVetoFocusListener; import bibliothek.gui.dock.common.intern.EfficientControlFactory; import bibliothek.gui.dock.common.intern.MutableCControlRegister; import bibliothek.gui.dock.common.intern.action.CActionImportanceOrder; import bibliothek.gui.dock.common.intern.action.CActionOffer; import bibliothek.gui.dock.common.intern.action.CButtonContentFilter; import bibliothek.gui.dock.common.intern.station.CFlapLayoutManager; import bibliothek.gui.dock.common.intern.station.CLockedResizeLayoutManager; import bibliothek.gui.dock.common.intern.station.CScreenDockStationWindowClosingStrategy; import bibliothek.gui.dock.common.intern.station.CommonDockStation; import bibliothek.gui.dock.common.intern.station.CommonDockStationFactory; import bibliothek.gui.dock.common.intern.ui.CDisablingStrategy; import bibliothek.gui.dock.common.intern.ui.CSingleParentRemover; import bibliothek.gui.dock.common.intern.ui.CommonSingleTabDecider; import bibliothek.gui.dock.common.intern.ui.ExtendedModeAcceptance; import bibliothek.gui.dock.common.intern.ui.StackableAcceptance; import bibliothek.gui.dock.common.intern.ui.WorkingAreaAcceptance; import bibliothek.gui.dock.common.layout.FullLockConflictResolver; import bibliothek.gui.dock.common.layout.RequestDimension; import bibliothek.gui.dock.common.mode.CLocationMode; import bibliothek.gui.dock.common.mode.CLocationModeManager; import bibliothek.gui.dock.common.mode.CMaximizedMode; import bibliothek.gui.dock.common.mode.CMaximizedModeArea; import bibliothek.gui.dock.common.mode.CStationContainerHistoryRewriter; import bibliothek.gui.dock.common.mode.ExtendedMode; import bibliothek.gui.dock.common.perspective.CControlPerspective; import bibliothek.gui.dock.common.perspective.CDockablePerspective; import bibliothek.gui.dock.common.perspective.CStackPerspective; import bibliothek.gui.dock.common.perspective.CStationPerspective; import bibliothek.gui.dock.common.perspective.CommonElementPerspective; import bibliothek.gui.dock.common.perspective.DefaultMissingPerspectiveFactory; import bibliothek.gui.dock.common.perspective.MissingPerspectiveStrategy; import bibliothek.gui.dock.common.theme.ThemeMap; import bibliothek.gui.dock.common.theme.eclipse.CommonEclipseThemeConnector; import bibliothek.gui.dock.control.DockRegister; import bibliothek.gui.dock.control.DockRelocatorMode; import bibliothek.gui.dock.control.DockableSelector; import bibliothek.gui.dock.control.focus.DefaultFocusStrategy; import bibliothek.gui.dock.control.focus.FocusStrategyRequest; import bibliothek.gui.dock.control.relocator.DefaultDockRelocator; import bibliothek.gui.dock.disable.DisablingStrategy; import bibliothek.gui.dock.displayer.SingleTabDecider; import bibliothek.gui.dock.dockable.DockableMovingImageFactory; import bibliothek.gui.dock.event.DockRegisterAdapter; import bibliothek.gui.dock.event.DockableFocusEvent; import bibliothek.gui.dock.event.DockableFocusListener; import bibliothek.gui.dock.event.DoubleClickListener; import bibliothek.gui.dock.event.KeyboardListener; import bibliothek.gui.dock.facile.mode.Location; import bibliothek.gui.dock.facile.mode.LocationModeManager; import bibliothek.gui.dock.facile.station.split.ConflictResolver; import bibliothek.gui.dock.facile.station.split.DefaultConflictResolver; import bibliothek.gui.dock.focus.DockableSelection; import bibliothek.gui.dock.frontend.FrontendEntry; import bibliothek.gui.dock.frontend.MissingDockableStrategy; import bibliothek.gui.dock.layout.DockSituationIgnore; import bibliothek.gui.dock.layout.DockableProperty; import bibliothek.gui.dock.perspective.PerspectiveDockable; import bibliothek.gui.dock.perspective.PerspectiveElement; import bibliothek.gui.dock.perspective.PerspectiveStation; import bibliothek.gui.dock.station.Combiner; import bibliothek.gui.dock.station.DisplayerFactory; import bibliothek.gui.dock.station.StationPaint; import bibliothek.gui.dock.station.flap.FlapWindow; import bibliothek.gui.dock.station.layer.DockStationDropLayerFactory; import bibliothek.gui.dock.station.screen.ScreenDockWindow; import bibliothek.gui.dock.station.stack.StackDockPerspective; import bibliothek.gui.dock.station.stack.StackDockStationFactory; import bibliothek.gui.dock.station.stack.StackDockStationLayout; import bibliothek.gui.dock.station.stack.action.DockActionDistributor; import bibliothek.gui.dock.station.stack.menu.CombinedMenuContent; import bibliothek.gui.dock.station.stack.tab.TabPane; import bibliothek.gui.dock.station.support.PlaceholderStrategy; import bibliothek.gui.dock.support.mode.HistoryRewriter; import bibliothek.gui.dock.support.util.ApplicationResource; import bibliothek.gui.dock.support.util.ApplicationResourceManager; import bibliothek.gui.dock.themes.BasicTheme; import bibliothek.gui.dock.themes.ColorScheme; import bibliothek.gui.dock.themes.ThemeFactory; import bibliothek.gui.dock.themes.basic.action.DockActionImportanceOrder; import bibliothek.gui.dock.themes.border.BorderModifier; import bibliothek.gui.dock.title.DockTitle; import bibliothek.gui.dock.util.AWTComponentCaptureStrategy; import bibliothek.gui.dock.util.BackgroundPaint; import bibliothek.gui.dock.util.DirectWindowProvider; import bibliothek.gui.dock.util.IconManager; import bibliothek.gui.dock.util.NullWindowProvider; import bibliothek.gui.dock.util.Priority; import bibliothek.gui.dock.util.PropertyKey; import bibliothek.gui.dock.util.WindowProvider; import bibliothek.gui.dock.util.extension.Extension; import bibliothek.gui.dock.util.extension.ExtensionManager; import bibliothek.gui.dock.util.extension.ExtensionName; import bibliothek.gui.dock.util.icon.DefaultIconScheme; import bibliothek.gui.dock.util.property.ConstantPropertyFactory; import bibliothek.gui.dock.util.text.DefaultTextScheme; import bibliothek.util.Filter; import bibliothek.util.Path; import bibliothek.util.Version; import bibliothek.util.xml.XElement; import bibliothek.util.xml.XException; import bibliothek.util.xml.XIO; /** * Manages the interaction between {@link SingleCDockable}, {@link MultipleCDockable} * and {@link CStation}s.
*/ public CContentArea createContentArea( String uniqueId ){ return createContentArea( uniqueId, false ); } private CContentArea createContentArea( String uniqueId, boolean isDefaultContentArea ){ if( uniqueId == null ) throw new NullPointerException( "uniqueId must not be null" ); if( !isDefaultContentArea && uniqueId.equals( CONTENT_AREA_STATIONS_ID )){ throw new IllegalArgumentException( "the unique identifier '" + uniqueId + "' is reserved for the default CContentArea and may not be used by the client" ); } CContentArea center = new CContentArea( this, uniqueId ); if( isDefaultContentArea ){ register.setDefaultContentArea( center ); } addStationContainer( center ); return center; } /** * Adds
* Clients which do no longer need a {@link CControl} can call {@link #destroy()} * to free resources.
* ACControl
is an interface between the application and the framework. The task of *CControl
is to provide access for actions that affect the entire realm. Such * actions may include: **
* @author Benjamin Sigg * */ public class CControl { /** * A key for this {@link CControl}. Will be set with the highest priority. To be used * wherever a {@link DockController} but not a {@link CControl} is accessible. */ public static final PropertyKey- add/remove a global listener.
*- add/remove/access {@link CDockable}s, {@link CStation}s and {@link CStationContainer}s.
*- add/remove/access factories for {@link CDockable}s.
*- read/write/apply the layout, this includes reading/writing from files.
*- store properties, like for example the {@link #setTheme(String) theme}.
*CCONTROL = new PropertyKey ( "ccontrol" ); /** * Name of an {@link ExtensionName} that adds extensions to this control. The extensions * are of type {@link Object} and are not actually used. Rather this extension informs * {@link Extension}s that a {@link CControl} has been created. */ public static final Path CCONTROL_EXTENSION = new Path( "dock.ccontrol" ); /** name of a parameter of an {@link ExtensionName} that points to this
*/ public static final String EXTENSION_PARAM = "control"; /** * {@link KeyStroke} used to change a {@link CDockable} into maximized-state, * or to go out of maximized-state when needed. */ public static final PropertyKeyKEY_MAXIMIZE_CHANGE = new PropertyKey ( "ccontrol.maximize_change" ); /** * {@link KeyStroke} used to change a {@link CDockable} into * maximized-state. */ public static final PropertyKey KEY_GOTO_MAXIMIZED = new PropertyKey ( "ccontrol.goto_maximized" ); /** * {@link KeyStroke} used to change a {@link CDockable} into * normalized-state. */ public static final PropertyKey KEY_GOTO_NORMALIZED = new PropertyKey ( "ccontrol.goto_normalized" ); /** * {@link KeyStroke} used to change a {@link CDockable} into * minimized-state. */ public static final PropertyKey KEY_GOTO_MINIMIZED = new PropertyKey ( "ccontrol.goto_minimized" ); /** * {@link KeyStroke} used to change a {@link CDockable} into * externalized-state. */ public static final PropertyKey KEY_GOTO_EXTERNALIZED = new PropertyKey ( "ccontrol.goto_externalized" ); /** * {@link KeyStroke} used to close a {@link CDockable}. */ public static final PropertyKey KEY_CLOSE = new PropertyKey ( "ccontrol.close" ); /** * {@link KeyStroke} that can be hit during a drag and drop operation, that will cancel the operation (default is ESCAPE). */ public static final PropertyKey KEY_CANCEL_OPERATION = new PropertyKey ( "ccontrol.cancel_dnd" ); /** * {@link ConflictResolver} used to determine what happens when there is * a conflict between two resize requests on a {@link SplitDockStation} like * {@link CGridArea}, {@link CWorkingArea} or {@link CContentArea}. * @see DefaultConflictResolver * @see FullLockConflictResolver */ public static final PropertyKey > RESIZE_LOCK_CONFLICT_RESOLVER = new PropertyKey >( "ccontrol.resize_lock_conflict_resolver", new ConstantPropertyFactory >( new DefaultConflictResolver ()), true ); /** * This factory creates the actions that close dockables. */ public static final PropertyKey CLOSE_ACTION_FACTORY = new PropertyKey ( "ccontrol.closeActionFactory", new ConstantPropertyFactory ( CloseActionFactory.DEFAULT ), true ); /** * The grouping behavior defines how {@link Dockable}s tend to automatically group together. */ public static final PropertyKey GROUPING_BEHAVIOR = new PropertyKey ( "ccontrol.groupingBehavior", new ConstantPropertyFactory ( new DefaultCGroupingBehavior() ), true ); /** the unique id of the station that handles the externalized dockables */ public static final String EXTERNALIZED_STATION_ID = "external"; /** the unique id of the default-{@link CContentArea} created by this control */ public static final String CONTENT_AREA_STATIONS_ID = "ccontrol"; /** connection to the real DockingFrames */ private CDockFrontend frontend; /** strategy what to do when reading layout information of a missing dockable */ private MissingCDockableStrategy missingStrategy = MissingCDockableStrategy.PURGE; /** access to internal methods of some {@link CDockable}s */ private Map accesses = new HashMap (); /** a manager allowing the user to change the extended-state of some {@link CDockable}s */ private CLocationModeManager locationManager; /** the default location of newly opened {@link CDockable}s */ private CLocation defaultLocation; /** a list of available {@link DockTheme}s */ private ThemeMap themes; /** Access to the internal methods of this control */ private CControlAccess access = new Access(); /** A strategy that can create missing {@link CStationPerspective} */ private MissingPerspectiveStrategy missingPerspectiveStrategy = new DefaultMissingPerspectiveFactory(); /** manager used to store and read configurations */ private ApplicationResourceManager resources = new ApplicationResourceManager(); /** a list of listeners which are to be informed when this control is no longer in use */ private List hooks = new ArrayList (); /** factory used to create new elements for this control */ private CControlFactory factory; /** the {@link CDockable}s and other elements used by this control */ private MutableCControlRegister register; /** the list of listeners to this {@link CControl} */ private List listeners = new ArrayList (); /** the list of resize-listeners */ private List resizeListeners = new ArrayList (); /** the collection of global listeners */ private CListenerCollection listenerCollection = new CListenerCollection(); /** the preferences used by this instance of {@link CControl} */ private PreferenceStorage preferences = new PreferenceStorage(); /** the model which is used to translate between {@link #preferences} and this
*/ private PreferenceModel preferenceModel; /** iftrue
, then minimizing a Dockable will automatically transfer focus to a not minimized Dockable */ private boolean transferFocusOnMinimize = true; /** * Creates a new control. Note that a control should know the main * window of the application, thus {@link CControl#CControl(WindowProvider)} * would be the better choice than this constructor. */ public CControl(){ this( new NullWindowProvider() ); } /** * Creates a new control * @param frame the main frame of the application, needed to create * dialogs for externalized {@link CDockable}s */ public CControl( JFrame frame ){ this( frame == null ? new NullWindowProvider() : new DirectWindowProvider( frame ) ); } /** * Creates a new control * @param restrictedEnvironment whether this application runs in a * restricted environment and is not allowed to listen for global events. * @deprecated it is not necessary to set therestrictedEnvironment
parameter anymore, the framework * will choose a fitting value itself */ @Deprecated public CControl( boolean restrictedEnvironment ){ this( new NullWindowProvider() ); getController().setRestrictedEnvironment( restrictedEnvironment ); } /** * Creates a new control * @param window a provider for the main window of this application. Needed * to create dialogs for externalized {@link CDockable}s. Must not benull
, but * its search method may returnnull
*/ public CControl( WindowProvider window ){ this( window, new EfficientControlFactory() ); } /** * Creates a new control * @param frame the main frame of the application, needed to create * dialogs for externalized {@link CDockable}s * @param restrictedEnvironment whether this application runs in a * restricted environment and is not allowed to listen for global events. * @deprecated it is not necessary to set therestrictedEnvironment
parameter anymore, the framework * will choose a fitting value itself */ @Deprecated public CControl( JFrame frame, boolean restrictedEnvironment ){ this( frame == null ? new NullWindowProvider() : new DirectWindowProvider( frame ) ); getController().setRestrictedEnvironment( restrictedEnvironment ); } /** * Creates a new control * @param window a provider for the main window of this application. Needed * to create dialogs for externalized {@link CDockable}s. Must not benull
, but * its search method may returnnull
* @param restrictedEnvironment whether this application runs in a * restricted environment and is not allowed to listen for global events. * @deprecated it is not necessary to set therestrictedEnvironment
parameter anymore, the framework * will choose a fitting value itself */ @Deprecated public CControl( WindowProvider window, boolean restrictedEnvironment ){ this( window ); getController().setRestrictedEnvironment( restrictedEnvironment ); } /** * Creates a new control * @param frame the main frame of the application, needed to create * dialogs for externalized {@link CDockable}s * @param factory a factory which is used to create new elements for this * control. */ public CControl( JFrame frame, CControlFactory factory ){ this( frame == null ? new NullWindowProvider() : new DirectWindowProvider( frame ), factory ); } /** * Creates a new control * @param window a provider for the main window of this application. Needed * to create dialogs for externalized {@link CDockable}s. Must not benull
, but * its search method may returnnull
* @param factory a factory which is used to create new elements for this * control. */ public CControl( WindowProvider window, CControlFactory factory ){ this( window, factory, true ); } /** * Creates a new control * @param window a provider for the main window of this application. Needed * to create dialogs for externalized {@link CDockable}s. Must not benull
, but * its search method may returnnull
* @param factory a factory which is used to create new elements for this * control. * @param init iftrue
then this constructor calls {@link #init(WindowProvider, CControlFactory)}, * otherwise this constructor does nothing and returns immediately. Subclasses should call * {@link #init(WindowProvider, CControlFactory)} in that case. */ protected CControl( WindowProvider window, CControlFactory factory, boolean init ){ if( init ){ init( window, factory ); } } /** * Initializes the fields of this {@link CControl}. This method is called during construction * of this {@link CControl}. Subclasses may use {@link #CControl(WindowProvider, CControlFactory, boolean)} * to create an uninitialized {@link CControl} and then call this method by themselves. * @param window a provider for the main window of this application. Needed * to create dialogs for externalized {@link CDockable}s. Must not benull
, but * its search method may returnnull
* @param factory a factory which is used to create new elements for this * control. */ protected void init( WindowProvider window, CControlFactory factory ){ if( window == null ){ throw new IllegalArgumentException( "window must not be null, however its search method may return null" ); } this.factory = factory; register = factory.createRegister( this ); DockController controller = factory.createController( this ); controller.getProperties().set( CCONTROL, this, Priority.CLIENT ); controller.getProperties().finalize( CCONTROL ); controller.setSingleParentRemover( new CSingleParentRemover( this ) ); initExtensions( controller ); initFocusListeners( controller ); initInputListener( controller ); initTransferFocusOnMinimize( controller ); frontend = factory.createFrontend( access, controller ); frontend.setOwner( window ); frontend.setMissingDockableStrategy( new MissingDockableStrategy(){ public boolean shouldStoreHidden( String key ) { return shouldStore( key ); } public boolean shouldStoreShown( String key ) { return shouldStore( key ); } publicboolean shouldCreate( DockFactory,?,L> factory, L data ) { if( factory instanceof CommonMultipleDockableFactory && data instanceof CommonMultipleDockableLayout ){ return CControl.this.shouldCreate( ((CommonMultipleDockableFactory)factory).getFactory(), (CommonMultipleDockableLayout)data ); } return false; } }); setIgnoreWorkingForEntry( true ); frontend.setShowHideAction( false ); frontend.getController().addActionOffer( new CActionOffer( this ) ); frontend.getController().getRegister().addDockRegisterListener( new DockRegisterAdapter(){ @Override public void dockableRegistered( DockController controller, Dockable dockable ) { if( dockable instanceof CommonDockable ){ CDockable cdock = ((CommonDockable)dockable).getDockable(); CDockableAccess access = accesses.get( cdock ); if( access != null ){ access.informVisibility( true ); } for( CControlListener listener : listeners() ) listener.opened( CControl.this, cdock ); } } @Override public void dockableUnregistered( DockController controller, Dockable dockable ) { if( dockable instanceof CommonDockable ){ CDockable cdock = ((CommonDockable)dockable).getDockable(); CDockableAccess access = accesses.get( cdock ); if( access != null ){ access.informVisibility( false ); } for( CControlListener listener : listeners() ) listener.closed( CControl.this, cdock ); if( cdock instanceof MultipleCDockable ){ MultipleCDockable multiple = (MultipleCDockable)cdock; if( multiple.isRemoveOnClose() ){ removeDockable( multiple ); } } } } }); frontend.getController().getFocusController().addVetoListener( new ControlVetoFocusListener( this, listenerCollection.getVetoFocusListener() ) ); frontend.getController().getFocusController().setStrategy( new DefaultFocusStrategy( frontend.getController() ){ public Component getFocusComponent( FocusStrategyRequest request ){ Component mouseClicked = request.getMouseClicked(); Dockable dockable = request.getDockable(); if( mouseClicked != null ){ if( (mouseClicked.isFocusable() && !excluded( mouseClicked, request )) || focusable( mouseClicked, request )){ return mouseClicked; } } if( dockable instanceof CommonDockable ){ Component result = ((CommonDockable)dockable).getDockable().getFocusComponent(); if( result != null ){ return result; } } return super.getFocusComponent( request ); } }); frontend.addVetoableListener( new ControlVetoClosingListener( this, listenerCollection.getVetoClosingListener() ) ); frontend.getController().addAcceptance( new StackableAcceptance() ); frontend.getController().addAcceptance( new WorkingAreaAcceptance( access ) ); frontend.getController().addAcceptance( new ExtendedModeAcceptance( access ) ); initFactories(); themes = new ThemeMap( this ); initPersistentStorage(); initExtendedModes(); initProperties(); initIcons(); initTexts(); setTheme( ThemeMap.KEY_SMOOTH_THEME ); controller.getExtensions().load( new ExtensionName container
to this control. All children {@link CStation}s ofcontainer
will * be added as root station to this control. * @param container the additional set of stations * @throws IllegalArgumentException ifcontainer
is already registered or if the unique identifier * ofcontainer
is already known * @throws NullPointerException ifcontainer
isnull
*/ public void addStationContainer( CStationContainer container ){ if( container == null ){ throw new NullPointerException( "container is null" ); } checkValidUniqueId( container.getUniqueId() ); // check control? DockStation defaultStation = frontend.getDefaultStation(); boolean noDefaultStation = defaultStation == null || defaultStation instanceof ScreenDockStation; register.addStationContainer( container ); if( noDefaultStation ){ CStation> newDefaultStation = container.getDefaultStation(); if( newDefaultStation != null ){ frontend.setDefaultStation( newDefaultStation.getStation() ); } } } /** * Removescontent
from the list of known contentareas. This also removes * the stations ofcontent
from this control. Elements aboard the * stations are made invisible, but not removed from this control. * @param content the contentarea to remove * @throws IllegalArgumentException if the default-contentarea equalscontent
* @deprecated use {@link #removeStationContainer(CStationContainer)} instead */ @Deprecated public void removeContentArea( CContentArea content ){ removeStationContainer( content ); } /** * Removescontainer
from the list of known {@link CStationContainer}s. This also * ensures that all child {@link CStation}s ofcontainer
are removed. Elements aboard the * stations are made invisible, but not removed from this {@link CControl}. * @param container the set of stations to remove * @throws IllegalArgumentException if container is the default {@link CContentArea} */ public void removeStationContainer( CStationContainer container ){ if( container == null ) throw new NullPointerException( "container must not be null" ); if( register.getDefaultContentArea() == container ) throw new IllegalArgumentException( "The default-contentarea can't be removed" ); register.removeStationContainer( container ); } /** * Gets the set of dockables, stations and other elements that are used * by this control. * @return the set of elements, nevernull
*/ public CControlRegister getRegister(){ return register; } /** * Gets an unmodifiable list of all {@link CStationContainer}s that are registered at this {@link CControl}. * @return the list of containers */ public ListgetStationContainers(){ return register.getStationContainers(); } /** * Gets the factory which is mainly used to create new elements for this * control. * @return the factory */ public CControlFactory getFactory() { return factory; } /** * Gets the manager that is responsible to handle all changes of the * modes (maximized, normalized, ... ) of {@link Dockable}s.
* Note: clients should be careful when working with the location manager. * Changing the properties of the location manager might introduce failures that * are not visible directly. * @return the manager */ public CLocationModeManager getLocationManager() { return locationManager; } /** * Adds a destroy-hook. The hook is called when this {@link CControl} is * destroyed through {@link #destroy()}. * @param hook the new hook */ public void addDestroyHook( DestroyHook hook ){ if( hook == null ) throw new NullPointerException( "hook must not be null" ); hooks.add( hook ); } /** * Removes a destroy-hook from this {@link CControl}. * @param hook the hook to remove */ public void removeDestroyHook( DestroyHook hook ){ hooks.remove( hook ); } /** * Grants access to the manager that reads and stores configurations * of the common-project.
* Clients can add their own {@link ApplicationResource}s to this manager, * however clients are strongly discouraged from removing {@link ApplicationResource} * which they did not add themselves. * @return the persistent storage */ public ApplicationResourceManager getResources() { return resources; } /** * Changes the value of a property. The incomplete list of properties, in alphabetical order, includes: * (properties marked with '*' should not be changed by clients if using the Common project). **
* * * @param the type of the value * @param key the name of the property * @param value the new value, can beProperties ** {@link BubbleTheme#ACTION_DISTRIBUTOR} Default instance of a {@link DockActionDistributor}. * {@link FlatTheme#ACTION_DISTRIBUTOR} Default instance of a {@link DockActionDistributor}. * {@link DefaultDockRelocator#AUTO_DROP_ON_ANY_MOUSE_RELEASED_EVENT} Stop drag-and-drop operations on any mouse-released event (a workaround necessary for some Linux and Mac systems). * {@link DockTheme#BACKGROUND_PAINT} The default value of the {@link BackgroundPaint}. * {@link BasicTheme#BASIC_COLOR_SCHEME} The {@link ColorScheme} to use if the {@link BasicTheme} is installed. * {@link DockTheme#BORDER_MODIFIER} The default value of the {@link BorderModifier}. * {@link ScreenDockStation#BOUNDARY_RESTRICTION} How far the user can push a window with a {@link Dockable} out of the screen(s). * {@link BubbleTheme#BUBBLE_COLOR_SCHEME} The {@link ColorScheme} to use if the {@link BubbleTheme} is installed. * {@link FlapDockStation#BUTTON_CONTENT} Tells what content should be on the buttons that represent minimized {@link Dockable}s. * {@link FlapDockStation#BUTTON_CONTENT_FILTER} Tells which {@link DockAction}s should be shown on a button representing a minimized {@link Dockable}. * * {@link CControl#CCONTROL} The {@link CControl} in whose realm the property is read, is a read-only property. * {@link DockTheme#COMBINER} Default value of the {@link Combiner}. * {@link StackDockStation#COMPONENT_FACTORY} The factory creating the "tabbed panes" of the {@link StackDockStation}. * {@link DockTheme#DISPLAYER_FACTORY} Default value of the {@link DisplayerFactory}. * {@link DockStationDropLayerFactory#DROP_LAYER_FACTORY} Factory that defines which parts of the screen are targets for a drag and drop operation/ * {@link PropertyKey#DOCK_STATION_ICON} The default icon of {@link DockStation}s. * {@link PropertyKey#DOCK_STATION_TITLE} The default title of {@link DockStation}s. * {@link PropertyKey#DOCK_STATION_TOOLTIP} The default tooltip of {@link DockStation}s. * {@link PropertyKey#DOCKABLE_ICON} The default icon of {@link Dockable}s. * {@link DockTheme#DOCKABLE_MOVING_IMAGE_FACTORY} Default value of the {@link DockableMovingImageFactory}. * {@link DockTheme#DOCKABLE_SELECTION} Default value of the {@link DockableSelection}. * {@link PropertyKey#DOCKABLE_TITLE} The default title of {@link Dockable}s. * {@link PropertyKey#DOCKABLE_TOOLTIP} The default tooltip of {@link Dockable}s. * {@link LocationModeManager#DOUBLE_CLICK_STRATEGY} Tells what happens if the user double clicks on a {@link DockTitle} or a {@link Dockable}. * {@link EclipseTheme#ECLIPSE_COLOR_SCHEME} The {@link ColorScheme} to use if the {@link EclipseTheme} is installed. * * {@link ScreenDockStation#EXPAND_ON_DOUBLE_CLICK} Whether a double click on a child of a {@link ScreenDockStation} should maximize the child. * {@link FlatTheme#FLAT_COLOR_SCHEME} The {@link ColorScheme} to use if the {@link FlatTheme} is installed. * {@link ScreenDockStation#FULL_SCREEN_STRATEGY} Defines when a floating {@link Dockable} is considered to be in fullscreen mode. * * {@link DockFrontend#HIDE_ACCELERATOR} The {@link KeyStroke} that will call {@link DockFrontend#hide(Dockable)} * {@link DockableSelector#INIT_SELECTION} The {@link KeyStroke} that opens a window where the user can select a new {@link Dockable}. * {@link StackDockStation#IMMUTABLE_SELECTION_INDEX} Prevents the {@link StackDockStation} from switching the selected index on a drop operation (but does not prevent the {@link FocusManager} from switching the focus!). * {@link CControl#KEY_CLOSE} The {@link KeyStroke} that closes a {@link CDockable}. * {@link CControl#KEY_GOTO_EXTERNALIZED} The {@link KeyStroke} that externalizes a {@link CDockable}. * {@link CControl#KEY_GOTO_MAXIMIZED} The {@link KeyStroke} that maximizes a {@link CDockable}. * {@link CControl#KEY_GOTO_MINIMIZED} The {@link KeyStroke} that minimizes a {@link CDockable}. * {@link CControl#KEY_GOTO_NORMALIZED} The {@link KeyStroke} that normalizes a {@link CDockable}. * {@link CControl#KEY_MAXIMIZE_CHANGE} The {@link KeyStroke} that either maximizes or normalizes a {@link CDockable}. * {@link CControl#KEY_CANCEL_OPERATION} The {@link KeyStroke} that will cancel the current drag and drop operation. * {@link FlapDockStation#LAYOUT_MANAGER} Tells the {@link FlapDockStation} the size and the hold property of its children. * {@link SplitDockStation#LAYOUT_MANAGER} Logic of all {@link SplitDockStation}s, used when dropping a {@link Dockable} or resizing the station. * {@link TabPane#LAYOUT_MANAGER} Defines the size and location of tabs of a stack. * {@link TabPane#USE_SMALL_MINIMUM_SIZE} Use really small minimum sizes for calculating the minimum size of a tab-pane, instead of trying to make the content look good * * {@link SplitDockStation#MAXIMIZE_ACCELERATOR} The {@link KeyStroke} that maximizes a child of a {@link SplitDockStation}. * {@link CombinedMenuContent#MENU_CONTENT} The menu that shows overflowing {@link Dockable}s on a stack. * {@link IconManager#MINIMUM_ICON_SIZE} The expected minimal size of all icons. * {@link FlapDockStation#MINIMUM_SIZE} The minimum size of the {@link Component} that represents the {@link FlapDockStation}. * * {@link LocationModeManager#MODE_ENABLEMENT} Tells which {@link CDockable} is allowed to have which {@link ExtendedMode}. * {@link DockRelocatorMode#NO_COMBINATION_MASK} What keys the user has to press during a drag and drop operation to prevent the framework from combining {@link Dockable}s. * {@link DockTitle#ORIENTATION_STRATEGY} Tells how to rotate text on a {@link DockTitle}. * {@link EclipseTheme#PAINT_ICONS_WHEN_DESELECTED} Whether to paint icons on unselected tabs if using the {@link EclipseTheme}. * {@link PlaceholderStrategy#PLACEHOLDER_STRATEGY} A strategy that creates placeholders for {@link Dockable}s, see {@link CPlaceholderStrategy}. * {@link CControl#RESIZE_LOCK_CONFLICT_RESOLVER} Tells what happens if two {@link CDockable}s have a locked size and the user is resizing the parent of these two elements. * {@link DockController#RESTRICTED_ENVIRONMENT} Tells whether the application runs as applet/with webstart or as free or authenticated application. * {@link DockRelocatorMode#SCREEN_MASK} The keys the user has to press during a drag and drop operation to ensure that the {@link Dockable} is added to a {@link ScreenDockStation}. * {@link SingleTabDecider#SINGLE_TAB_DECIDER} Tells which {@link Dockable}s should be presented with a single tab - even if there is no reason to show a tab. * {@link DockTheme#STATION_PAINT} The default value of {@link StationPaint}. * {@link AWTComponentCaptureStrategy#STRATEGY} How to make an image of an AWT component. * {@link DisablingStrategy#STRATEGY} Which element to disable. * {@link StackDockStation#TAB_CONTENT_FILTER} A filter deciding what content to show on a tab of a {@link StackDockStation}. * {@link EclipseTheme#TAB_PAINTER} The look of tabs if using the {@link EclipseTheme}. * {@link StackDockStation#TAB_PLACEMENT} The location of the tabs on a {@link StackDockStation}. * {@link EclipseTheme#THEME_CONNECTOR} Detailed instructions how to present a {@link Dockable} if using the {@link EclipseTheme}. * {@link FlapDockStation#WINDOW_FACTORY} A factory creating {@link FlapWindow}s for the {@link FlapDockStation}. * {@link ScreenDockStation#WINDOW_FACTORY} A factory creating {@link ScreenDockWindow}s for the {@link ScreenDockStation}. null
*/ public void putProperty( PropertyKey key, A value ){ putProperty( key, value, Priority.CLIENT ); } /** * Changes the value of a property. * @param the type of the value * @param key the name of the property * @param priority the priority of the new value * @param value the new value, can benull
* @see #putProperty(PropertyKey, Object) */ protected void putProperty( PropertyKey key, A value, Priority priority ){ frontend.getController().getProperties().set( key, value, priority ); } /** * Gets the value of a property. * @param the type of the property * @param key the name of the property * @return the value ornull
*/ public A getProperty( PropertyKey key ){ return frontend.getController().getProperties().get( key ); } /** * Gets the element that should be in the center of the mainframe. The {@link CContentArea} * is created the first time this method is called. * @return the center of the mainframe of the application */ public CContentArea getContentArea() { CContentArea content = register.getDefaultContentArea(); if( content == null ){ content = createContentArea( CONTENT_AREA_STATIONS_ID, true ); } return content; } /** * Adds an additional station to this control. * @param station the new station */ public void addStation( CStation> station ){ addStation( station, true ); } /** * Adds an additional station to this control. Most {@link CStation}s should * be root-stations, even if they are nested. * @param station the new station * @param roottrue
if the station should be a root station. A root station may * or may not have any parent station. The location of a {@link CDockable} is always relative * to the first root station that can be found when travelling the tree upwards. For most stations * this attribute should betrue
*/ public void addStation( CStation> station, boolean root ){ String id = station.getUniqueId(); checkValidUniqueId( id ); register.addStation( station ); if( root ){ frontend.addRoot( id, station.getStation() ); } station.setControlAccess( access ); } /** * Tells whetherstation
was {@link #addStation(CStation, boolean) added} to this {@link CControl} * with theroot
flag set totrue
. * @param station the station whose root flag is asked * @return the value of the root flag orfalse
ifstation
is not registered at all */ public boolean isRootStation( CStation> station ){ DockStation root = frontend.getRoot( station.getUniqueId() ); return root == station.getStation(); } /** * Removes a {@link CStation} from this control. It is unspecified what * happens with the children onstation
* @param station the station to remove */ public void removeStation( CStation> station ){ if( register.removeStation( station ) ){ frontend.removeRoot( station.getStation() ); station.setControlAccess( null ); } } /** * Gets an unmodifiable list of all stations that are currently * registered at this control. * @return the list of stations */ public List> getStations(){ return register.getStations(); } /** * Searches the {@link CStation} whose {@link CStation#getStation() internal representation} * is intern
. * @param intern the internal representation * @return the station ornull
*/ public CStation> getStation( DockStation intern ){ if( intern instanceof CommonDockStation,?>){ return ((CommonDockStation, ?>)intern).getStation(); } return null; } /** * Searches along the path to the root {@link DockStation} the first {@link CStation} that matches * the {@link DockStation}. Ifintern
is a {@link CStation}, then this method behaves * as if {@link #getStation(DockStation)} was called. If the parent ofintern
is a {@link CStation}, * then this method behaves as ifgetStation( intern.getDockParent() )
was called. * @param intern the starting point for the search of a {@link CStation} * @return the next {@link CStation} on the path fromintern
(incl.) to the root station (incl.) */ public CStation> findStation( DockStation intern ){ CStation> result = null; while( result == null && intern != null ){ result = getStation( intern ); Dockable dockable = intern.asDockable(); if( dockable == null ){ intern = null; }else{ intern = dockable.getDockParent(); } } return result; } /** * Searches the {@link CStation} with unique identifierid
. * @param id the identifier * @return the station ornull
*/ public CStation> getStation( String id ){ for( CStation> station : register.getStations() ){ if( station.getUniqueId().equals( id )){ return station; } } return null; } /** * Adds a dockable to this control. The dockable can be made visible afterwards. This method will do nothing * ifdockable
was already registered at this {@link CControl}. * @paramthe type of the new element * @param dockable the new element to show * @returndockable
* @throws IllegalArgumentException ifdockable
already is registered at another {@link CControl} * or if the unique id ofdockable
already is used for another object */ publicS addDockable( S dockable ){ if( dockable == null ) throw new NullPointerException( "dockable must not be null" ); checkValidUniqueId( dockable.getUniqueId() ); boolean alreadyKnown = dockable.getControl() == this; if( dockable.getControl() != null && !alreadyKnown ){ throw new IllegalArgumentException( "dockable is already part of a control" ); } SingleCDockable preset = register.getSingleDockable( dockable.getUniqueId() ); if( preset != null ){ if( preset == dockable ){ return dockable; } else{ throw new IllegalArgumentException( "unique id \'" + dockable.getUniqueId() + "\' already in use for another SingleCDockable" ); } } if( !alreadyKnown ){ dockable.setControlAccess( access ); } String id = register.toSingleId( dockable.getUniqueId() ); accesses.get( dockable ).setUniqueId( id ); frontend.addDockable( id, dockable.intern() ); frontend.setHideable( dockable.intern(), true ); register.addSingleDockable( dockable ); for( CControlListener listener : listeners() ) listener.added( CControl.this, dockable ); return dockable; } /** * Checks whether the unique identifierid
is a valid identifier. This means thatid
* is notnull
and contains at least one sign that is not a whitespace. * @param id the unique identifier to check * @throws IllegalArgumentException ifid
is not valid */ private void checkValidUniqueId( String id ){ if( id == null ){ throw new IllegalArgumentException( "unique id is 'null'"); } if( id.length() == 0 ){ throw new IllegalArgumentException( "unique id has length of 0" ); } if( id.trim().length() == 0 ){ throw new IllegalArgumentException( "unique id consists of whitespaces only" ); } } /** * Searches for the {@link SingleCDockable} which has the unique identifier *id
. * @param id the identifier to look out for * @return the element with that identifier ornull
*/ public SingleCDockable getSingleDockable( String id ){ for( SingleCDockable dockable : register.getSingleDockables() ){ if( dockable.getUniqueId().equals( id )){ return dockable; } } return null; } /** * Removes the {@link SingleCDockable} with the identifierid
. * @param id the id of the element to remove * @returntrue
if the element was removed,false
* otherwise */ public boolean removeSingleDockable( String id ){ for( SingleCDockable dockable : register.getSingleDockables() ){ if( dockable.getUniqueId().equals( id )){ return removeDockable( dockable ); } } return false; } /** * Removesdockable
from this control. The location information * fordockable
remains stored if either there is a * {@link #addSingleDockableFactory(String, SingleCDockableFactory) SingleCDockableFactory} * registered or the {@link #setMissingStrategy(MissingCDockableStrategy) MissingCDockableStrategy} * tells to store the values. * @param dockable the element to remove * @return true if the element was removed,false
otherwise */ public boolean removeDockable( SingleCDockable dockable ){ if( dockable == null ) throw new NullPointerException( "dockable must not be null" ); if( dockable.getControl() == this ){ dockable.setVisible( false ); frontend.remove( dockable.intern() ); register.removeSingleDockable( dockable ); dockable.setControlAccess( null ); for( CControlListener listener : listeners() ) listener.removed( CControl.this, dockable ); return true; } return false; } /** * Adds a factory to this control. The factory will be used * to create and add a {@link SingleCDockable} when one is requested that * is not yet in the cache.
* If there is already information forid
available and *id
should be visible, then the factory will be used * instantaneously.
* Factories added with a specific identifier always have higher priority than factories * added with a filter, see {@link #addSingleDockableFactory(Filter, SingleCDockableFactory)}. * @param id the id of the dockable that might be requested * @param backupFactory the new factory */ public void addSingleDockableFactory( String id, SingleCDockableFactory backupFactory ){ register.getBackupFactory().add( id, backupFactory ); String singleId = register.toSingleId( id ); // This would happen automatically when loading a layout. However code reading // the entries of DockFrontend is now informed about the possible existence of // such an identifier locationManager.addEmpty( singleId ); frontend.addEmpty( singleId ); // if there is already layout information for id, then load this information now FrontendEntry entry = frontend.getFrontendEntry( singleId ); if( entry != null && entry.getDockable() == null && entry.isShown() ){ SingleCDockable dockable = backupFactory.createBackup( id ); if( dockable != null ){ addDockable( dockable ); if( entry.isShown() || !dockable.isCloseable() ){ dockable.setVisible( true ); } } } } /** * Adds a factory to this control. The factory will be used * to create and add a {@link SingleCDockable} when one is requested that * is not yet in the cache.
* If there is already information for identifiers that are included byids
available and * if they should be visible, then thefactory
will be used instantaneously to create these elements. * During this actionfactory
has a higher priority than any other factory.
* Factories added with a general filter always have lower priority than factories that were added * with a specific identifier. The factories are stored in a list and a search starts at the front of that * list, so a factory added early has higher priority than a factory that was added lately. * @param ids a filter telling which dockables can be handled byfactory
* @param factory the new factory */ public void addSingleDockableFactory( Filterids, SingleCDockableFactory factory ){ register.getBackupFactory().add( ids, factory ); for( FrontendEntry entry : frontend.listFrontendEntries() ){ if( entry.getDockable() == null && entry.isShown() ){ if( register.isSingleId( entry.getKey() )){ String id = register.singleToNormalId( entry.getKey() ); if( ids.includes( id )){ SingleCDockable dockable = factory.createBackup( id ); if( dockable != null ){ addDockable( dockable ); if( entry.isShown() || !dockable.isCloseable() ){ dockable.setVisible( true ); } } } } } } } /** * Searches the {@link SingleCDockableFactory} which is responsible for creating the * {@link SingleCDockable} with identifier id
. This method first searches * for a factory which was added with a specific identifier ({@link #addSingleDockableFactory(String, SingleCDockableFactory)}), * if nothing is found then the factories with a filter are searched ({@link #addSingleDockableFactory(Filter, SingleCDockableFactory)}). * @param id the identifier of some factory * @return the factory ornull
*/ public SingleCDockableFactory getSingleDockableFactory( String id ){ return register.getBackupFactory().getFactory( id ); } /** * Removes all occurrences offactory
. Any location information that was held * because of the existence offactory
will be removed as well. * @param factory the factory to remove */ public void removeSingleDockableFactory( SingleCDockableFactory factory ){ register.getBackupFactory().remove( factory ); for( FrontendEntry entry : frontend.listFrontendEntries() ){ if( entry.getDockable() == null && entry.isShown() ){ if( register.isSingleId( entry.getKey() )){ String id = register.singleToNormalId( entry.getKey() ); if( !missingStrategy.shouldStoreSingle( id )){ locationManager.removeEmpty( entry.getKey()); frontend.removeEmpty( entry.getKey() ); } } } } } /** * Removes a factory from this control. Location information for *id
will be deleted if neither a {@link #addDockable(SingleCDockable) SingleCDockable} * is added nor the {@link #setMissingStrategy(MissingCDockableStrategy) MissingCDockableStrategy} * tells to store the information. * @param id the name of the factory * @see #addSingleDockableFactory(String, SingleCDockableFactory) */ public void removeSingleDockableFactory( String id ){ register.getBackupFactory().remove( id ); if( !missingStrategy.shouldStoreSingle( id )){ id = register.toSingleId( id ); locationManager.removeEmpty( id ); frontend.removeEmpty( id ); } } /** * Adds a dockable to this control. The dockable can be made visible afterwards. A random identifier * is assigned todockable
, clients can also use {@link #addDockable(String, MultipleCDockable)} if * they want to specify the identifier themselves. * @paramthe type of the new element * @param dockable the new element to show * @return dockable
* @throws IllegalArgumentException if either the {@link MultipleCDockable#getFactory() factory} ofdockable
isnull
, * or is not registered (see {@link #addMultipleDockableFactory(String, MultipleCDockableFactory)}). */ publicM addDockable( M dockable) { Set ids = new HashSet (); String factoryId; MultipleCDockableFactory, ?> factory = dockable.getFactory(); if( factory == null ){ throw new IllegalArgumentException( "factory of dockable must not be null" ); } factoryId = access.getFactoryId( dockable.getFactory() ); if( factoryId == null ){ throw new IllegalStateException( "the factory for a MultipleCDockable is not registered: " + dockable.getFactory() ); } for( MultipleCDockable multi : register.getMultipleDockables() ){ if( factoryId.equals( access.getFactoryId( multi.getFactory() ))){ ids.add( accesses.get( multi ).getUniqueId() ); } } int count = 0; String id = count + " " + factoryId; while( ids.contains( register.toMultiId( id ) ) ){ count++; id = count + " " + factoryId; } return addDockable( id, dockable ); } /** * Adds a dockable to this control. The dockable can be made visible afterwards. * This method will throw an exception when the unique identifier is already * in use. Clients can also use {@link #addDockable(MultipleCDockable)} if they want to assign a * random identifier to dockable
. * @paramthe type of the new element * @param uniqueId id the unique id of the new element * @param dockable the new element to show * @return dockable
* @throws IllegalArgumentException if the unique identifier is already in * use, ifdockable
is already used elsewhere, if there is * no factory fordockable
* @throws NullPointerException if any argument isnull
*/ publicM addDockable( String uniqueId, M dockable ){ if( dockable == null ) throw new NullPointerException( "dockable must not be null" ); checkValidUniqueId( uniqueId ); String factory = access.getFactoryId( dockable.getFactory() ); if( factory == null ){ throw new IllegalStateException( "the factory for a MultipleCDockable is not registered: " + dockable.getFactory() ); } if( dockable.getControl() != null ) throw new IllegalStateException( "dockable is already part of a control" ); uniqueId = register.toMultiId( uniqueId ); for( MultipleCDockable multi : register.getMultipleDockables() ){ String id = accesses.get( multi ).getUniqueId(); if( uniqueId.equals( id )){ throw new IllegalArgumentException( "The unique identifier is already in use: " + uniqueId ); } } dockable.setControlAccess( access ); accesses.get( dockable ).setUniqueId( uniqueId ); frontend.addDockable( uniqueId, dockable.intern() ); frontend.setHideable( dockable.intern(), true ); register.addMultipleDockable( dockable ); for( CControlListener listener : listeners() ) listener.added( CControl.this, dockable ); return dockable; } /** * Replaces oldDockable
withnewDockable
. The new dockable * inherits settings and location of the old one. * @param oldDockable the old dockable, notnull
* @param newDockable the new dockable, notnull
*/ public void replace( MultipleCDockable oldDockable, MultipleCDockable newDockable ){ if( oldDockable == null ) throw new IllegalArgumentException( "old dockable must not be null" ); if( newDockable == null ) throw new IllegalArgumentException( "new dockable must not be null" ); if( oldDockable.getControl() != this ) throw new IllegalArgumentException( "old dockable not registered at this CControl" ); if( newDockable.getControl() != null ) throw new IllegalArgumentException( "new dockable alread registered at some CControl" ); String id = accesses.get( oldDockable ).getUniqueId(); boolean frontendEmpty = frontend.isEmpty( id ); if( !frontendEmpty ){ frontend.addEmpty( id ); } boolean locationEmpty = locationManager.isEmpty( id ); if( !locationEmpty ){ locationManager.addEmpty( id ); } id = register.multiToNormalId( id ); removeDockable( oldDockable ); addDockable( id, newDockable ); if( !frontendEmpty ){ frontend.removeEmpty( id ); } if( !locationEmpty ){ locationManager.removeEmpty( id ); } } /** * Searches and returns the one {@link MultipleCDockable} which uses * the unique identifierid
. * @param id the identifier to look out for * @return the element usingid
ornull
if nothing * was found */ public MultipleCDockable getMultipleDockable( String id ){ id = register.toMultiId( id ); for( MultipleCDockable dockable : register.getMultipleDockables() ){ if( accesses.get( dockable ).getUniqueId().equals( id )){ return dockable; } } return null; } /** * Gets the unique identifier which is used internally fordockable
* @param dockable the item to search * @return the internal unique identifier ofdockable
, may benull
*/ public String getUniqueId( MultipleCDockable dockable ){ CDockableAccess access = accesses.get( dockable ); if( access == null ){ return null; } return register.multiToNormalId( access.getUniqueId() ); } private boolean shouldStore( String id ){ if( register.isSingleId( id )){ if( register.getBackupFactory().getFactory( register.singleToNormalId( id ) ) != null ){ return true; } return missingStrategy.shouldStoreSingle( register.singleToNormalId( id ) ); } else if( register.isMultiId( id )){ return missingStrategy.shouldStoreMulti( register.multiToNormalId( id ) ); } else{ return false; } } private String shouldStore( CDockable dockable ){ String key = null; if( dockable instanceof SingleCDockable ){ key = ((SingleCDockable)dockable).getUniqueId(); key = register.toSingleId( key ); } else if( dockable instanceof MultipleCDockable ){ CDockableAccess access = accesses.get( dockable ); if( access == null ){ return null; } key = access.getUniqueId(); } if( shouldStore( key )){ return key; } else{ return null; } } @SuppressWarnings("unchecked") private boolean shouldCreate( MultipleCDockableFactory, ?> factory, CommonMultipleDockableLayout layout ){ String uniqueId = layout.getId(); String multiId = register.toMultiId( uniqueId ); for( MultipleCDockable multi : register.getMultipleDockables() ){ if( accesses.get( multi ).getUniqueId().equals( multiId )){ return false; } } String factoryId = access.getFactoryId( factory ); MultipleCDockableFactory, MultipleCDockableLayout> normalizedFactory = (MultipleCDockableFactory, MultipleCDockableLayout>)factory; return missingStrategy.shouldCreate( factoryId, normalizedFactory, uniqueId, layout.getLayout() ); } /** * Removes a dockable from this control. The dockable is made invisible. * @param dockable the element to remove */ public void removeDockable( MultipleCDockable dockable ){ if( dockable == null ) throw new NullPointerException( "dockable must not be null" ); if( dockable.getControl() == this ){ dockable.setVisible( false ); frontend.remove( dockable.intern() ); register.removeMultipleDockable( dockable ); dockable.setControlAccess( null ); for( CControlListener listener : listeners() ) listener.removed( CControl.this, dockable ); } } /** * Gets the number of {@link CDockable}s that are registered in this * {@link CControl}. * @return the number of dockables */ public int getCDockableCount(){ return register.getDockableCount(); } /** * Gets the index'th dockable that is registered in this control * @param index the index of the element * @return the selected dockable */ public CDockable getCDockable( int index ){ return register.getDockable( index ); } /** * Adds a factory to this control. The factory will create {@link MultipleCDockable}s * when a layout is loaded. The {@link NullMultipleCDockableFactory} will always be preinstalled using * the empty identifier. * @param id the unique id of the factory, must consist of at least one character * @param factory the new factory */ public void addMultipleDockableFactory( final String id, final MultipleCDockableFactory,?> factory ){ addMultipleDockableFactory( id, factory, true ); } private void addMultipleDockableFactory( final String id, final MultipleCDockableFactory,?> factory, boolean check ){ if( check ){ checkValidUniqueId( id ); } if( factory == null ){ throw new NullPointerException( "factory must not be null" ); } if( register.getCommonMultipleDockableFactory( id ) != null ){ throw new IllegalArgumentException( "there is already a factory named " + id ); } if( access.getFactoryId( factory ) != null ){ throw new IllegalArgumentException( "this factory-object is already in use and cannot be added a second time" ); } CommonMultipleDockableFactory cfactory = new CommonMultipleDockableFactory( id, factory, access ); register.putCommonMultipleDockableFactory( id, cfactory ); frontend.registerFactory( cfactory ); } /** * Searches for the {@link MultipleCDockableFactory} with the identifier *id
. * @param id the identifier to search for * @return the factory ornull
*/ public MultipleCDockableFactory, ?> getMultipleDockableFactory( String id ){ return register.getFactory( id ); } /** * Gets the unique identifier offactory
. * @param factory the factory to search * @return the unique identifier ornull
*/ public String getFactoryId( MultipleCDockableFactory, ?> factory ){ return access.getFactoryId( factory ); } /** * Removes the {@link MultipleCDockableFactory} with identifierid
* from this control. As a side effect all {@link MultipleCDockable}s which * use that factory are removed as well. Nothing happens if there is no * factory registered withid
. * @param id the identifier of the factory to remove */ public void removeMultipleDockableFactory( String id ){ CommonMultipleDockableFactory factory = register.removeCommonMultipleDockableFactory( id ); if( factory != null ){ frontend.unregisterFactory( factory ); ListtoRemove = new ArrayList (); for( MultipleCDockable dockable : register.getMultipleDockables() ){ if( dockable.getFactory() == factory.getFactory() ){ toRemove.add( dockable ); } } for( MultipleCDockable dockable : toRemove ){ removeDockable( dockable ); } } } /** * Sets the location where {@link CDockable}s are opened when there is * nothing else specified for these CDockable
s. * @param defaultLocation the location, can benull
*/ public void setDefaultLocation( CLocation defaultLocation ){ this.defaultLocation = defaultLocation; } /** * Gets the location where {@link CDockable}s are opened when nothing else * is specified. * @return the location, might benull
* @see #setDefaultLocation(CLocation) */ public CLocation getDefaultLocation(){ return defaultLocation; } /** * Makes sure that all {@link CDockable}s are maximized onto the area * which is registered under the given unique id. * @param id the unique id of the area * @see CGridArea#getUniqueId() * @see CContentArea#getCenterIdentifier() */ public void setMaximizeArea( String id ){ CMaximizedMode mode = locationManager.getMaximizedMode(); CMaximizedModeArea area = mode.get( id ); if( area == null ) throw new IllegalArgumentException( "No area registered with key '" + id + "'" ); mode.setDefaultArea( area ); } /** * Sets the {@link CGroupBehavior}. The behavior decides what happens when the user wants to change * the {@link ExtendedMode} of a {@link CDockable}.
* To be exact: the group behavior is applied for a call to {@link CDockable#setExtendedMode(ExtendedMode)} * respective a call to {@link LocationModeManager#setMode(Dockable, ExtendedMode)}. The buttons that are * visible to the user all link to these methods. * @param behavior the new behavior, notnull
*/ public void setGroupBehavior( CGroupBehavior behavior ){ locationManager.setGroupBehavior( behavior ); } /** * Gets the currently used {@link CGroupBehavior}. * @return the current behavior, notnull
* @see #setGroupBehavior(CGroupBehavior) */ public CGroupBehavior getGroupBehavior(){ return locationManager.getGroupBehavior(); } /** * Sets the theme of the elements in the realm of this control. * @param theme the new theme * @deprecated replaced by {@link #setTheme(String)}. While this method still * works, the theme will not get stored persistent and any module using * the {@link ThemeMap} ({@link #getThemes()}) will not be informed about * the change. */ @Deprecated public void setTheme( DockTheme theme ){ frontend.getController().setTheme( theme ); } /** * Sets the theme of the elements in the realm of this control. The String *theme
is used as key for {@link ThemeMap#select(String)}. * @param theme the name of the theme, this might be one of * {@link ThemeMap#KEY_BASIC_THEME}, {@link ThemeMap#KEY_BUBBLE_THEME}, * {@link ThemeMap#KEY_ECLIPSE_THEME}, {@link ThemeMap#KEY_FLAT_THEME} * or {@link ThemeMap#KEY_SMOOTH_THEME}. This can also be a any other * string which was used for {@link ThemeMap#put(String, ThemeFactory)}, * {@link ThemeMap#add(String, ThemeFactory)} or {@link ThemeMap#insert(int, String, ThemeFactory)}. */ public void setTheme( String theme ){ themes.select( theme ); } /** * Gets the list of installed themes. * @return the list of themes */ public ThemeMap getThemes(){ return themes; } /** * Sets a strategy that creates missing {@link CStationPerspective}s. * @param missingPerspectiveStrategy the strategy, notnull
*/ public void setMissingPerspectiveStrategy( MissingPerspectiveStrategy missingPerspectiveStrategy ){ if( missingPerspectiveStrategy == null ){ throw new IllegalArgumentException( "strategy must not be null" ); } this.missingPerspectiveStrategy = missingPerspectiveStrategy; } /** * Gets the strategy that is used to create missing {@link CStationPerspective}. * @return the strategy, notnull
*/ public MissingPerspectiveStrategy getMissingPerspectiveStrategy(){ return missingPerspectiveStrategy; } /** * Grants access to the perspective API which allows clients to build complex layouts without * the need to create any {@link CDockable dockables} or {@link CStation stations}. * @return access a wrapper around this {@link CControl} allowing to inspect and modify the layouts * that are available * @see #load(String) * @see #save(String) * @see #setMissingPerspectiveStrategy(MissingPerspectiveStrategy) */ public CControlPerspective getPerspectives(){ return new CControlPerspective( access ); } /** * Sets the root window of the application. The root window is used * as owner of any dialog that is created. Already existing dialogs * may be closed and reopened in order to change the owner. Short living * dialogs will not change their owner. * @param window the new owner, can benull
*/ public void setRootWindow( WindowProvider window ){ frontend.setOwner( window ); } /** * Gets the root window of the application. Note that this method might * not return the same object as given to {@link #setRootWindow(WindowProvider)}, * however the provide returned by this method will return the same window * as specified by {@link #setRootWindow(WindowProvider)}. * @return the provider, nevernull
*/ public WindowProvider getRootWindow(){ return frontend.getOwner(); } /** * Gets the storage container for {@link PreferenceModel}s for this control. * The contents of this container are stored in the * {@link #getResources() resource manager}. * @return the storage for preferences * @see #getResources() */ public PreferenceStorage getPreferences(){ return preferences; } /** * Sets the {@link PreferenceModel} which will be used to translate between *this
and the {@link #getPreferences() preferences}. This * model can be set tonull
.
* The default value of this property isnull
. * @param preferenceModel the new model, it will used to translate * the contents of {@link #getPreferences()} immediately, can benull
*/ public void setPreferenceModel( PreferenceModel preferenceModel ) { if( this.preferenceModel != null ){ this.preferenceModel.read(); preferences.store( this.preferenceModel ); } this.preferenceModel = preferenceModel; if( preferenceModel != null ){ preferences.load( preferenceModel, false ); preferenceModel.write(); } } /** * Gets the preference model which is used to translate between the * {@link #getPreferences() preferences} andthis
. * @return the model, can benull
* @see #setPreferenceModel(PreferenceModel) */ public PreferenceModel getPreferenceModel() { return preferenceModel; } /** * Sets the strategy that tells what to do if layout information of a missing * {@link CDockable} is found. * @param missingStrategy the strategy,null
will set * the default strategy */ public void setMissingStrategy( MissingCDockableStrategy missingStrategy ) { if( missingStrategy == null ){ this.missingStrategy = MissingCDockableStrategy.PURGE; } else{ this.missingStrategy = missingStrategy; } } /** * Gets the strategy that tells what to do if layout information of a missing * {@link CDockable} is found. * @return the strategy, nevernull
*/ public MissingCDockableStrategy getMissingStrategy() { return missingStrategy; } /** * Adds a {@link ResizeRequestListener} to this {@link CControl}. The listener * will be informed when the resize requests of a {@link CDockable} should * be processed. * @param listener the new listener, notnull
*/ public void addResizeRequestListener( ResizeRequestListener listener ){ if( listener == null ) throw new NullPointerException( "listener must not be null" ); resizeListeners.add( listener ); } /** * Removes a {@link ResizeRequestListener} from this {@link CControl}. * @param listener the listener to remove */ public void removeResizeRequestListener( ResizeRequestListener listener ){ resizeListeners.remove( listener ); } /** * Informs all {@link ResizeRequestListener}s, that the * {@link CDockable#getAndClearResizeRequest() resize request} of all *CDockable
s should be processed. There are no * guarantees that a resize requests can be granted or even gets processed.
* All requests, independent from whether they were processed, will be deleted * by this method.
* Note that a request might conflict with a "resize lock" * {@link CDockable#isResizeLockedHorizontally()} and * {@link CDockable#isResizeLockedVertically()}. The behavior of that case is not * specified, but clients can assume that the locked components introduce * additional resize requests. */ public void handleResizeRequests(){ ResizeRequestListener[] listeners = resizeListeners.toArray( new ResizeRequestListener[ resizeListeners.size() ] ); for( ResizeRequestListener listener : listeners ) listener.handleResizeRequest( this ); for( CDockable dockable : register.getDockables() ) dockable.getAndClearResizeRequest(); } /** * Gets the representation of the layer beneath the common-layer. * @return the entry point to DockingFrames */ public CDockFrontend intern(){ return frontend; } /** * Gets the {@link DockController} which is used by this {@link CControl}. * @return the core system of the framework */ public DockController getController(){ return intern().getController(); } /** * Grants access to all the {@link Icon}s that are used within the realm of this * {@link CControl}. Clients are free to modify the set of icons. * @return the set of icons that are used */ public IconManager getIcons(){ return getController().getIcons(); } /** * Tells this control whether basic modes like "normalized", "minimized" or "externalized" are forced upon * {@link Dockable}s after loading a persistent layout. Basically if this property is set, then all {@link Dockable}s * are un-maximized after a layout change. The default value of this property istrue
.
* The reasons behind forcing basic modes are: **
* @param revert whether non-basic modes should be forbidden when loading a persistent layout */ public void setRevertToBasicModes( boolean revert ){ intern().setRevertToBasicModes( revert ); } /** * Tells whether basic modes are forcibly applied when loading a persistent layout. * @return whether the non-basic modes are forbidden * @see #setRevertToBasicModes(boolean) */ public boolean isRevertToBasicModes(){ return intern().isRevertToBasicModes(); } /** * If a {@link CDockable} is minimized, the focus can be automatically transferred to another {@link CDockable}. This * feature is implemented by the method {@link #initTransferFocusOnMinimize(DockController)}, which may be * overridden by subclasses. * @param transferFocusOnMinimize whether to enable the feature or not (default is- If the user changes the layout, he/she most likely would like to see the effects. A maximized {@link Dockable} would * hide the effects.
*- For the user re-maximizing an element requires no more than one click with the mouse. It's a cheap operation.
*- It is an additional layer of security preventing {@link Dockable}s from being in the wrong position if the client * was stared with new settings.
*true
) */ public void setTransferFocusOnMinimize( boolean transferFocusOnMinimize ){ this.transferFocusOnMinimize = transferFocusOnMinimize; } /** * If a {@link CDockable} is minimized, the focus can be automatically transferred to another {@link Dockable}. * @return whether the focus will be transferred * @see #setTransferFocusOnMinimize(boolean) */ public boolean isTransferFocusOnMinimize(){ return transferFocusOnMinimize; } /** * Writes the current and all known layouts intofile
.
* This is the same as callinggetResources().writeFile( file )
. * @param file the file to override * @throws IOException if the file can't be written */ public void write( File file ) throws IOException{ getResources().writeFile( file ); } /** * Writes the current and all known layouts intoout
.
* This is the same as callinggetResources().writeStream( out )
. * @param out the stream to write into * @throws IOException if the stream is not writable */ public void write( DataOutputStream out ) throws IOException{ getResources().writeStream( out ); } /** * Writes the current and all known layouts intoelement
.
* This is the same as callinggetResources().writeXML( element )
. * @param element the element to write into */ public void writeXML( XElement element ){ getResources().writeXML( element ); } /** * Writes the current and all known layouts intofile
in xml format. * @param file the file to write into * @throws IOException if the file is not writable */ public void writeXML( File file ) throws IOException{ XElement root = new XElement( "root" ); getResources().writeXML( root ); BufferedOutputStream out = new BufferedOutputStream( new FileOutputStream( file )); XIO.writeUTF( root, out ); out.close(); } /** * Reads the current and other known layouts fromfile
.
* This is the same as callinggetResources().readFile( file )
. * @param file the file to read from * @throws IOException if the file can't be read */ public void read( File file ) throws IOException{ getResources().readFile( file ); } /** * Reads the current and other known layouts fromin
.
* This is the same as callinggetResources().readStream( in )
. * @param in the stream to read from * @throws IOException if the stream can't be read */ public void read( DataInputStream in ) throws IOException{ getResources().readStream( in ); } /** * Reads the current and other known layouts fromelement
.
* This is the same as callinggetResources().readXML( element )
. * @param element the element to read * @throws XException if the xml file has the wrong structure */ public void readXML( XElement element ){ getResources().readXML( element ); } /** * Reads the current and other known layouts fromfile
. * @param file the file to open and to read * @throws IOException if the file cannot be read * @throws XException if the xml file has the wrong structure */ public void readXML( File file ) throws IOException{ BufferedInputStream in = new BufferedInputStream( new FileInputStream( file )); XElement element = XIO.readUTF( in ); in.close(); readXML( element ); } /** * Saves the current layout with the current name. Does nothing if there is no name for the current layout. * @return the name that was used to save the layout * @see #save(String) */ public String save(){ return save( false ); } /** * Saves the current layout with the current name. Does nothing if there is no name for the current layout. * @param includeWorkingAreas whether the content of the {@link CStation}s that are marked as * {@link CStation#isWorkingArea() working area} should be stored as well. * @return the name that was used to save the layout * @see #save(String) */ public String save( boolean includeWorkingAreas ){ String current = frontend.getCurrentSetting(); if( current == null ){ return null; } else{ save( current, includeWorkingAreas ); return current; } } /** * Stores the current layout with the given name. This creates "entry" (partial) layout information. * @param name the name of the current layout. */ public void save( String name ){ frontend.save( name ); } /** * Stores the current layout with the given name. This creates "entry" (partial) layout information. * @param name the name of the current layout. * @param includeWorkingAreas whether the content of the {@link CStation}s that are marked as * {@link CStation#isWorkingArea() working area} should be stored as well. */ public void save( String name, boolean includeWorkingAreas ){ frontend.save( name, !includeWorkingAreas ); } /** * Loads an earlier stored layout. * @param name the name of the layout. */ public void load( String name ){ frontend.load( name ); } /** * Loads an earlier stored layout. * @param name the name of the layout. * @param includeWorkingAreas whether the content of the {@link CStation}s that are marked as * {@link CStation#isWorkingArea() working area} should be updated as well. This value should be the same * as was used to call {@link #save(String, boolean)}. */ public void load( String name, boolean includeWorkingAreas ){ frontend.load( name, !includeWorkingAreas ); } /** * Deletes a layout that has been stored earlier. * @param name the name of the layout to delete */ public void delete( String name ){ frontend.delete( name ); } /** * Gets a list of all layouts that are currently known. * @return the list of layouts */ public String[] layouts(){ Setsettings = frontend.getSettings(); return settings.toArray( new String[ settings.size() ] ); } /** * Gets the name of the current layout (the one with which {@link #save(String)} was called). The current * layout may not have a name if it was never saved. The result of this method will be a {@link String} * that is part of {@link #layouts()}. * @return the name of the current layout, or null
*/ public String getLayout(){ return frontend.getCurrentSetting(); } /** * A class giving access to the internal methods of the enclosing * {@link CControl}. * @author Benjamin Sigg */ private class Access implements CControlAccess{ /** action used to close {@link CDockable}s */ private DockAction closeAction; public CControl getOwner(){ return CControl.this; } public void link( CDockable dockable, CDockableAccess access ) { if( access == null ){ CDockableAccess oldAccess = accesses.remove( dockable ); if( oldAccess != null ){ oldAccess.setUniqueId( null ); } dockable.removeCDockablePropertyListener( listenerCollection.getCDockablePropertyListener() ); dockable.removeCDockableStateListener( listenerCollection.getCDockableStateListener() ); } else{ if( accesses.put( dockable, access ) == null ){ dockable.addCDockablePropertyListener( listenerCollection.getCDockablePropertyListener() ); dockable.addCDockableStateListener( listenerCollection.getCDockableStateListener() ); } } } public CDockableAccess access( CDockable dockable ) { return accesses.get( dockable ); } public void hide( CDockable dockable ){ if( !dockable.isVisible() ) return; DockRegister register = frontend.getController().getRegister(); try{ register.setStalled( true ); MapnonBasic = new HashMap (); for( Dockable check : locationManager.listDockables() ){ if( check != dockable.intern() ){ CLocationMode mode = locationManager.getCurrentMode( check ); if( mode != null && !mode.isBasicMode() ){ nonBasic.put( check, mode.getExtendedMode() ); } } } Dockable[] focusHistory = getController().getFocusHistory().getHistory(); boolean changes = locationManager.ensureBasicModes(); frontend.hide( dockable.intern() ); if( changes ){ for( Dockable focused : focusHistory ){ ExtendedMode mode = nonBasic.get( focused ); if( mode != null ){ if( frontend.isShown( focused ) && locationManager.isModeAvailable( focused, mode )){ locationManager.setMode( focused, mode ); } } } } } finally{ register.setStalled( false ); } } public void show( CDockable dockable ){ if( dockable.hasParent() ) return; DockRegister register = frontend.getController().getRegister(); register.setStalled( true ); try{ CLocation location = dockable.getAutoBaseLocation( true ); CDockableAccess access = access( dockable ); if( access != null ){ access.internalLocation( true ); } CStation> area = dockable.getWorkingArea(); if( area != null && area.asDockable() != null ){ if( !area.asDockable().isVisible() ){ throw new IllegalStateException( "A dockable that wants to be on a working-area can't be made visible unless the working-area is visible." ); } } if( location == null ){ dockable.setExtendedMode( findInitialMode( dockable ) ); } else{ locationManager.setLocation( dockable.intern(), location ); } if( !frontend.isShown( dockable.intern() )){ frontend.show( dockable.intern(), false ); } locationManager.ensureValidLocation( dockable ); } finally{ register.setStalled( false ); } } private ExtendedMode findInitialMode( CDockable dockable ){ CGroupingBehavior groupingBehavior = getProperty( GROUPING_BEHAVIOR ); DockableGrouping grouping = groupingBehavior.getGrouping( dockable.intern() ); ExtendedMode mode = null; if( grouping != null ){ mode = grouping.getInitialMode( dockable.intern() ); } if( mode == null ){ mode = ExtendedMode.NORMALIZED; } return mode; } public CLocation getAutoBaseLocation( CDockable dockable, boolean noBackwardsTransformation ){ CDockableAccess access = access( dockable ); CLocation location = null; if( access != null ){ location = access.internalLocation( false ); } if( location == null ){ if( frontend.hasLocation( dockable.intern() )){ FrontendEntry entry = frontend.getFrontendEntry( dockable.intern() ); String root = entry.getRoot(); DockableProperty property = entry.getLocation(); CStation> station = getStation( root ); if( station != null ){ if( noBackwardsTransformation ){ return null; } location = station.getStationLocation().expandProperty( getController(), property ); } } if( location == null ){ CStation> area = dockable.getWorkingArea(); if( area != null ){ location = area.getStationLocation(); } if( location == null ){ location = defaultLocation; } if( location == null && !noBackwardsTransformation ){ location = locationManager.getLocation( dockable.intern(), ExtendedMode.NORMALIZED ); } } } return location; } public boolean isVisible( CDockable dockable ){ return frontend.isShown( dockable.intern() ); } public boolean hasParent( CDockable dockable ){ if( frontend.isHiddenRootStation( dockable.intern() )){ return false; } return isVisible( dockable ); } public String getFactoryId( MultipleCDockableFactory,?> factory ){ for( Map.Entry > entry : register.getFactories().entrySet() ){ if( entry.getValue() == factory ){ return entry.getKey(); } } return null; } public CLocationModeManager getLocationManager() { return locationManager; } public DockAction createCloseAction( final CDockable dockable ) { if( closeAction == null ){ CloseActionFactory factory = getController().getProperties().get( CLOSE_ACTION_FACTORY ); closeAction = factory.create( CControl.this, dockable ).intern(); } return closeAction; } public MutableCControlRegister getRegister() { return register; } public boolean shouldStore( String key ) { return CControl.this.shouldStore( key ); } public String shouldStore( CDockable dockable ) { return CControl.this.shouldStore( dockable ); } } }
© 2015 - 2025 Weber Informatics LLC | Privacy Policy