/* * 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) 2008 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 * benjamin_sigg@gmx.ch * CH - Switzerland */ package bibliothek.gui; import java.awt.Component; import javax.swing.Icon; import javax.swing.event.MouseInputListener; import bibliothek.gui.dock.DefaultDockable; import bibliothek.gui.dock.DockElement; import bibliothek.gui.dock.DockElementRepresentative; import bibliothek.gui.dock.action.DockAction; import bibliothek.gui.dock.action.DockActionSource; import bibliothek.gui.dock.action.HierarchyDockActionSource; import bibliothek.gui.dock.displayer.DisplayerRequest; import bibliothek.gui.dock.displayer.DockableDisplayerHints; import bibliothek.gui.dock.dockable.AbstractDockable; import bibliothek.gui.dock.dockable.DockableStateListener; import bibliothek.gui.dock.event.DockActionSourceListener; import bibliothek.gui.dock.event.DockHierarchyEvent; import bibliothek.gui.dock.event.DockHierarchyListener; import bibliothek.gui.dock.event.DockableListener; import bibliothek.gui.dock.station.DockableDisplayer; import bibliothek.gui.dock.station.support.PlaceholderListItem; import bibliothek.gui.dock.title.DockTitle; import bibliothek.gui.dock.title.DockTitleFactory; import bibliothek.gui.dock.title.DockTitleRequest; import bibliothek.gui.dock.title.DockTitleVersion; import bibliothek.util.Todo; import bibliothek.util.Todo.Compatibility; import bibliothek.util.Todo.Priority; import bibliothek.util.Todo.Version; /** * A <code>Dockable</code> is a window which can be dragged around by the user. <code>Dockable</code>s * need to have a {@link DockStation} as parent, otherwise they are not visible.<br> * Several properties are associated with a <code>Dockable</code>: * <ul> * <li>A set of {@link DockTitle}s is managed by the parent of this <code>Dockable</code>. The icon and the title-text * of this <code>Dockable</code> might be painted on that title.</li> * <li>A set of {@link DockAction}s is stored in a {@link DockActionSource}. These actions are displayed * on the title(s) and allow users to execute operations that belong to this <code>Dockable</code></li> * <li>A {@link Component} which represents the contents of this <code>Dockable</code></li> * </ul> * This interface is not intended to be implemented by clients, although they can if some very special behavior is required. * Normally clients are better of using the {@link DefaultDockable} or extending {@link AbstractDockable}. * @author Benjamin Sigg */ public interface Dockable extends DockElement, DockElementRepresentative, PlaceholderListItem<Dockable>{ /** * Sets the parent property. This Dockable is shown as direct child of * <code>station</code>.<br> * Note: this method has to fire a {@link bibliothek.gui.dock.event.DockHierarchyEvent}.<br> * Note: when using a {@link bibliothek.gui.dock.dockable.DockHierarchyObserver}, invoke * {@link bibliothek.gui.dock.dockable.DockHierarchyObserver#update()} after the * property has changed, it will automatically fire a {@link DockHierarchyEvent} if necessary. * @param station the parent, may be <code>null</code> if this <code>Dockable</code> is not visible at all. */ public void setDockParent( DockStation station ); /** * Gets the current parent, which is the latest argument of {@link #setDockParent(DockStation)}. * @return the parent property, can be <code>null</code> */ public DockStation getDockParent(); /** * Tells whether this {@link Dockable} can be seen by the user. A {@link Dockable} at least needs * to be registered as root-station on a {@link DockController}, or be a child of a root-station * to be visible.<br> * Implementations will assume that {@link Component}s which are {@link Component#isDisplayable() displayable} are * are visible to the user. * @return <code>true</code> if the user can actually see this dockable, <code>false</code> * otherwise * @deprecated replaced by {@link #isDockableShowing()}, this method will be removed in a future release */ @Deprecated @Todo( compatibility=Compatibility.BREAK_MAJOR, priority=Priority.ENHANCEMENT, target=Version.VERSION_1_1_3, description="remove this method" ) public boolean isDockableVisible(); /** * Tells whether this {@link Dockable} can be seen by the user. A {@link Dockable} at least needs * to be registered as root-station on a {@link DockController}, or be a child of a root-station * to be visible.<br> * Implementations will assume that {@link Component}s which are {@link Component#isDisplayable() displayable} are * are visible to the user. * @return <code>true</code> if the user can actually see this dockable, <code>false</code> * otherwise */ public boolean isDockableShowing(); /** * Sets the controller in whose realm this Dockable is. A value of <code>null</code> * means that this {@link Dockable} is not managed by a controller.<br> * Note: this method has to inform all {@link DockHierarchyListener}s about the change.<br> * Note: when using a {@link bibliothek.gui.dock.dockable.DockHierarchyObserver}, invoke * {@link bibliothek.gui.dock.dockable.DockHierarchyObserver#controllerChanged(DockController)} * @param controller the owner, may be <code>null</code> */ public void setController( DockController controller ); /** * Gets the current controller, the argument of the last call of * {@link #setController(DockController)}. * @return the controller, can be <code>null</code> */ public DockController getController(); /** * Adds a listener to this Dockable. The listener has to be informed if * a property of this Dockable changes. * @param listener the new listener */ public void addDockableListener( DockableListener listener ); /** * Removes a listener from this Dockable. * @param listener the listener to remove */ public void removeDockableListener( DockableListener listener ); /** * Adds a hierarchy-listener to this Dockable. The listener has to be * informed whenever the path to this Dockable has been changed.<br> * Subclasses might use the {@link bibliothek.gui.dock.dockable.DockHierarchyObserver} * to implement this feature in an easy way. Subclasses then only have * to call {@link bibliothek.gui.dock.dockable.DockHierarchyObserver#update()} * whenever the {@link #setDockParent(DockStation) parent} of this Dockable * changes.<br> * Note: when using a {@link bibliothek.gui.dock.dockable.DockHierarchyObserver}, * forward the call directly to {@link bibliothek.gui.dock.dockable.DockHierarchyObserver#addDockHierarchyListener(DockHierarchyListener)} * @param listener the new listener */ public void addDockHierarchyListener( DockHierarchyListener listener ); /** * Removes a hierarchy-listener from this Dockable.<br> * Note: when using a {@link bibliothek.gui.dock.dockable.DockHierarchyObserver}, * forward the call directly to {@link bibliothek.gui.dock.dockable.DockHierarchyObserver#removeDockHierarchyListener(DockHierarchyListener)} * @param listener the listener to remove * @see #addDockableListener(DockableListener) */ public void removeDockHierarchyListener( DockHierarchyListener listener ); /** * Adds <code>listener</code> to this {@link Dockable}. The listener will be informed about * various events concerning the position and visibility of this dockable. * @param listener the new listener, not <code>null</code> */ public void addDockableStateListener( DockableStateListener listener ); /** * Removes <code>listener</code> from this element. * @param listener the listener to remove */ public void removeDockableStateListener( DockableStateListener listener ); /** * Adds a {@link MouseInputListener} to the {@link #getComponent() component} of this <code>Dockable</code>. * A <code>Dockable</code> has to decide by itself which {@link Component Components} * should be observer, but generally all free areas should be covered. * It's also possible just to ignore the listener, but that's not the * preferred behavior. * @param listener the mouse listener */ public void addMouseInputListener( MouseInputListener listener ); /** * Removes a listener that was earlier added to this <code>Dockable</code>. * @param listener The listener to remove */ public void removeMouseInputListener( MouseInputListener listener ); /** * Tells whether <code>station</code> is an accepted parent for this * <code>Dockable</code> or not. The user is not able to drag a <code>Dockable</code> to a station * which is not accepted. * @param station a possible parent * @return whether <code>station</code> could be a parent or not */ public boolean accept( DockStation station ); /** * Tells whether <code>base</code> could be the parent of a combination * between this <code>Dockable</code> and <code>neighbor</code>. The user is not able * to make a combination between this <code>Dockable</code> and <code>neighbor</code> * if this method does not accept the operation. * @param base the future parent of the combination * @param neighbor a <code>Dockable</code> whose parent will be the same parent as * the parent of this <code>Dockable</code> * @return <code>true</code> if the combination is allowed, <code>false</code> * otherwise */ public boolean accept( DockStation base, Dockable neighbor ); /** * Gets the {@link Component} which represents this <code>Dockable</code>. Note that * the component should be a {@link java.awt.Container#setFocusCycleRoot(boolean) focus cycle root} * @return the visible representation */ public Component getComponent(); /** * Gets the current title-text of this <code>Dockable</code>. * @return the text */ public String getTitleText(); /** * Gets a tooltip that is associated with this <code>Dockable</code> and * that should be shown on any {@link DockTitle}. * @return the tooltip, can be <code>null</code> */ public String getTitleToolTip(); /** * Gets the current icon of this <code>Dockable</code>. * @return the icon, may be <code>null</code> */ public Icon getTitleIcon(); /** * Invoked to get a graphical representation of a title for this <code>Dockable</code>. This method is * called either when a title first is required, or when this {@link Dockable} * invoked the {@link DockableListener#titleExchanged(Dockable, DockTitle)} method of its * current observers. <br> * This {@link Dockable} might decide to answer the request by calling * {@link DockTitleRequest#answer(DockTitle)}, any title, including <code>null</code> are * valid answers. If this {@link Dockable} does not answer the request the associated * {@link DockTitleFactory} (as described by {@link DockTitleVersion#getFactory()}) is * asked to answer the request.<br> * The requests {@link DockTitleRequest#getTarget() target} must be this {@link Dockable}.<br> * The normal behavior of this method is to do nothing. * @param request which title is required. If this Dockable does not have * a special rule for the given request it just ignores the call */ public void requestDockTitle( DockTitleRequest request ); /** * Invoked to get {@link DockableDisplayer} for this {@link Dockable}. This method may be called when * this {@link Dockable} is dropped onto a new {@link DockStation}, a theme was exchanged, or an existing * {@link DockableDisplayer} was discarded.<br> * The usual behavior of this method should be to do nothing. * @param request callback used to set a new {@link DockableDisplayer} */ public void requestDisplayer( DisplayerRequest request ); /** * Called by clients which want to show a title of this <code>Dockable</code>. The * method {@link DockTitle#bind()} will be called automatically by the * controller.<br> * This method must at least inform all listeners, that <code>title</code> * was bound. However, the method {@link DockTitle#bind()} must not * be invoked by this method.<br> * <code>title</code> must be returned by {@link #listBoundTitles()} * unless {@link #unbind(DockTitle)} is called.<br> * @param title the title which will be show some things of this <code>Dockable</code> * @see #unbind(DockTitle) * @throws IllegalArgumentException if the title is already bound */ public void bind( DockTitle title ); /** * Clients should call this method if a {@link DockTitle} is no longer * needed. The controller will call {@link DockTitle#unbind()} at an appropriate * time.<br> * This method must inform all listeners that <code>title</code> * is no longer bound. However, this method must not call * {@link DockTitle#unbind()}.<br> * <code>title</code> must no longer be returned when calling {@link #listBoundTitles()} * @param title the title which will be no longer connected to this <code>Dockable</code> * @see #bind(DockTitle) * @throws IllegalArgumentException if the title is not known to this <code>Dockable</code> */ public void unbind( DockTitle title ); /** * Gets a list of all {@link DockTitle DockTitles} which are currently * bound to this <code>Dockable</code>. That are titles for which {@link #bind(DockTitle)} * was called, but not yet {@link #unbind(DockTitle)}. * @return the list of titles */ public DockTitle[] listBoundTitles(); /** * Gets a list of {@link DockAction}s which should be triggerable if * this <code>Dockable</code> is visible. The list contains only actions which are * directly bound to this <code>Dockable</code> (the actions which are not changed when * the parent-station of this <code>Dockable</code> is exchanged). * The list can be modified by this <code>Dockable</code> at every time, clients have * to react on these changes by adding a {@link DockActionSourceListener} to the result. * @return the source of actions, can be <code>null</code> if no actions * are available */ public DockActionSource getLocalActionOffers(); /** * Gets a list of all {@link bibliothek.gui.dock.action.DockAction}s which * might be triggered while this <code>Dockable</code> is visible. The list must contain * all actions which are related in any way to this <code>Dockable</code>. Subclasses * might use a {@link HierarchyDockActionSource} or the method * {@link DockController#listOffers(Dockable)} to implement this functionality * @return the source containing all actions, never <code>null</code> */ public DockActionSource getGlobalActionOffers(); /** * Orders this <code>Dockable</code> to configure <code>hints</code> which will * be used by the parent component of this element. This <code>Dockable</code> * can store a reference to <code>hints</code> and use it to change the * hints whenever it is appropriate. This method will be called with <code>null</code> * if the link should be broken. * @param hints the hints to configure or <code>null</code> if the last * <code>hints</code> should no longer be configured by this element */ public void configureDisplayerHints( DockableDisplayerHints hints ); }