/* * 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) 2010 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.dock.themes.basic.action; import java.awt.Component; import java.util.HashMap; import java.util.Map; import bibliothek.gui.DockController; import bibliothek.gui.Dockable; import bibliothek.gui.dock.action.ActionDockBorder; import bibliothek.gui.dock.action.DockAction; import bibliothek.gui.dock.action.DockActionBackgroundComponent; import bibliothek.gui.dock.themes.ThemeManager; import bibliothek.gui.dock.themes.border.BorderModifier; import bibliothek.gui.dock.util.BackgroundAlgorithm; import bibliothek.gui.dock.util.BackgroundPaint; import bibliothek.gui.dock.util.UIValue; /** * Collection of methods that are interesting for classes that wrap around a {@link BasicButtonModel}. * @author Benjamin Sigg */ public class AbstractBasicHandler<D extends DockAction, M extends BasicButtonModel> implements BasicResourceInitializer{ /** the action which is observed */ private D action; /** the model which is handled by this handler */ private M model; /** the dockable for which the action is displayed */ private Dockable dockable; /** the background algorithm to be used */ private Background background = new Background(); /** all the borders which are managed by this handler */ private Map<String, BorderHandle> borders = new HashMap<String, BorderHandle>(); /** whether this handler is in use */ private boolean bound = false; /** * Creates a new handler. * @param action the action which will be observed. * @param dockable the dockable for which the action is shown */ public AbstractBasicHandler( D action, Dockable dockable ){ if( action == null ) throw new IllegalArgumentException( "Action must not be null" ); this.dockable = dockable; this.action = action; } /** * Gets the dockable whose action is handled. * @return the dockable, not <code>null</code> */ public Dockable getDockable(){ return dockable; } /** * Gets the action which is read by this handler. * @return the action, not <code>null</code> */ public D getAction(){ return action; } /** * Gets the model which is written by this handler. * @return the model, not <code>null</code> */ public M getModel(){ return model; } public void ensureBorder( BasicButtonModel model, String key ){ addBorder( key ); } /** * Adds a connection between the {@link ThemeManager} and the model of this handler which transfers * the {@link BorderModifier} with identifier <code>key</code> to the model. Nothing happens if such a * connection already exists. * @param key the identifier of the {@link BorderModifier} to transfer */ public void addBorder( String key ){ if( borders.get( key ) == null ){ BorderHandle handle = new BorderHandle( key ); borders.put( key, handle ); if( bound ){ handle.setController( dockable.getController() ); } } } /** * Sets the model to which all properties of the {@link #getAction() action} * are transferred. * @param model the model */ public void setModel( M model ) { this.model = model; for( BorderHandle handle : borders.values() ){ if( handle.modifier != null ){ model.setBorder( handle.id, handle.modifier ); } } if( bound ){ model.setController( dockable.getController() ); } } public void bind(){ if( !bound ){ bound = true; DockController controller = dockable.getController(); background.setController( controller ); for( BorderHandle handle : borders.values() ){ handle.setController( controller ); } model.setController( controller ); } } public void unbind(){ if( bound ){ bound = false; background.setController( null ); for( BorderHandle handle : borders.values() ){ handle.setController( null ); } model.setController( null ); } } /** * Tells whether {@link #bind()} was called. * @return <code>true</code> if this handler is in use, <code>false</code> otherwise */ public boolean isBound(){ return bound; } /** * The background algorithm to be used by the {@link BasicHandler#getModel() model}. * @author Benjamin Sigg */ private class Background extends BackgroundAlgorithm implements DockActionBackgroundComponent{ public Background(){ super( DockActionBackgroundComponent.KIND, ThemeManager.BACKGROUND_PAINT + ".action" ); } @Override public void set( BackgroundPaint value ){ super.set( value ); model.setBackground( getPaint(), this ); } public DockAction getAction(){ return action; } public Dockable getDockable(){ return dockable; } public Component getComponent(){ return model.getOwner(); } } /** * A {@link BorderModifier} that is used by the representation of the model. * @author Benjamin Sigg */ private class BorderHandle implements ActionDockBorder{ /** the identifier of this value */ private String id; /** the current modifier of the border */ private BorderModifier modifier; /** the current controller */ private DockController controller; /** * Creates a new wrapper. * @param id the identifier of this value */ public BorderHandle( String id ){ this.id = id; } /** * Links this {@link UIValue} with <code>controller</code>. * @param controller the new source of values, can be <code>null</code> */ public void setController( DockController controller ){ if( this.controller != null ){ this.controller.getThemeManager().remove( this ); } this.controller = controller; if( this.controller == null ){ set( null ); } else{ this.controller.getThemeManager().add( id, ActionDockBorder.KIND, ThemeManager.BORDER_MODIFIER_TYPE, this ); } } public void set( BorderModifier value ){ if( modifier != value ){ modifier = value; if( model != null ){ model.setBorder( id, value ); } } } public DockAction getAction(){ return action; } public Dockable getDockable(){ return dockable; } } }