All Downloads are FREE. Search and download functionalities are using the official Maven repository.

bibliothek.gui.dock.facile.action.KeyedActionSource Maven / Gradle / Ivy

Go to download

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

There is a newer version: 1.1.2p20b.fix-1
Show newest version
/*
 * 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
 * [email protected]
 * CH - Switzerland
 */
package bibliothek.gui.dock.facile.action;

import java.util.Iterator;

import bibliothek.gui.dock.action.AbstractDockActionSource;
import bibliothek.gui.dock.action.DockAction;
import bibliothek.gui.dock.action.DockActionSource;
import bibliothek.gui.dock.action.LocationHint;
import bibliothek.gui.dock.common.action.CAction;
import bibliothek.gui.dock.common.event.CDockableAdapter;
import bibliothek.gui.dock.common.event.CDockablePropertyListener;
import bibliothek.gui.dock.common.intern.CDockable;
import bibliothek.gui.dock.event.DockActionSourceListener;
import bibliothek.util.FrameworkOnly;

/**
 * An action source using {@link CDockable#getAction(String)} to determine which
 * action to use. If getAction returns null, then
 * a default action can be used. This action source also allows to disable any
 * action.
 * @author Benjamin Sigg
 */
@FrameworkOnly
public class KeyedActionSource extends AbstractDockActionSource {
	/** the observed element */
	private CDockable dockable;
	
	/** the key of the action to handle */
	private String key;
	
	/** the default action to be used if {@link CDockable#getAction(String)} returns null */
	private DockAction defaultAction;
	
	/** the location of this source */
	private LocationHint hint = LocationHint.UNKNOWN;
	
	/** whether to show an action at all or not */
	private boolean visible = true;

	/** whether {@link #propertyListener} is added to {@link #dockable} */
	private boolean propertyListenerInstalled = false;
	
	/** a listener observing {@link #dockable} */
	private CDockablePropertyListener propertyListener = new CDockableAdapter(){
		public void actionChanged( CDockable dockable, String key, CAction oldAction, CAction newAction ){
			if( visible ){
				boolean shown = (oldAction != null) || (defaultAction != null);
				boolean showing = (newAction != null) || (defaultAction != null);
				
				if( shown && !showing )
					fireRemoved( 0, 0 );
				else if( !shown && showing )
					fireAdded( 0, 0 );
				else if( shown && showing ){
					visible = false;
					fireRemoved( 0, 0 );
					visible = true;
					fireAdded( 0, 0 );
				}
			}
		}
	};

	/**
	 * Creates a new action source
	 * @param dockable the element for which this source is used
	 * @param key the key for calling {@link CDockable#getAction(String)}
	 */
	public KeyedActionSource( CDockable dockable, String key ){
		if( dockable == null )
			throw new IllegalArgumentException( "dockable must not be null" );
		if( key == null )
			throw new IllegalArgumentException( "key must not be null" );
		this.dockable = dockable;
		this.key = key;
	}
	
	/**
	 * Gets the key which is used for calling {@link CDockable#getAction(String)}
	 * @return the key, not null
	 */
	public String getKey(){
		return key;
	}
	
	@Override
	public void addDockActionSourceListener( DockActionSourceListener listener ){
		super.addDockActionSourceListener( listener );
		if( visible && !propertyListenerInstalled && !listeners.isEmpty() ){
			dockable.addCDockablePropertyListener( propertyListener );
			propertyListenerInstalled = true;
		}
	}
	
	@Override
	public void removeDockActionSourceListener( DockActionSourceListener listener ){
		super.removeDockActionSourceListener( listener );
		if( visible && propertyListenerInstalled && listeners.isEmpty() ){
			dockable.removeCDockablePropertyListener( propertyListener );
			propertyListenerInstalled = false;
		}
	}
	
	/**
	 * Detaches the listeners this {@link DockActionSource} added to
	 * other objects.
	 */
	public void destroy(){
		if( propertyListenerInstalled ){
			dockable.removeCDockablePropertyListener( propertyListener );
			propertyListenerInstalled = false;
		}
	}
	
	/**
	 * Changes whether any actions are shown or not.
	 * @param visible the new state
	 */
	public void setVisible( boolean visible ){
		if( this.visible != visible ){
			int current = getDockActionCount();
			this.visible = visible;
			
			if( visible ){
				if( !propertyListenerInstalled && !listeners.isEmpty() ){
					dockable.addCDockablePropertyListener( propertyListener );
					propertyListenerInstalled = true;
				}
			}
			else{
				if( propertyListenerInstalled ){
					dockable.removeCDockablePropertyListener( propertyListener );
					propertyListenerInstalled = false;
				}
			}
			int updated = getDockActionCount();
			
			if( current < updated )
				fireAdded( 0, 0 );
			else if( current > updated )
				fireRemoved( 0, 0 );
		}
	}
	
	/**
	 * Sets the default action of this source. The default action
	 * is used if {@link CDockable#getAction(String)} returns
	 * null.
	 * @param defaultAction the default action, may be null
	 */
	public void setDefaultAction( DockAction defaultAction ){
		if( visible ){
			if( dockable.getAction( key ) == null ){
				visible = false;
				fireRemoved( 0, 0 );
				this.defaultAction = defaultAction;
				visible = true;
				fireAdded( 1, 1 );
			}
			else{
				this.defaultAction = defaultAction;
			}
		}
		else{
			this.defaultAction = defaultAction;
		}
	}
	
	/**
	 * Gets the default action of this source.
	 * @return the default action, can be null
	 */
	public DockAction getDefaultAction(){
		return defaultAction;
	}
	
	/**
	 * Gets the action that is currently to be shown.
	 * @return the current action or null if invisible or not available.
	 */
	private DockAction currentAction(){
		if( !visible )
			return null;
		
		CAction result = dockable.getAction( key );
		if( result == null ){
			return defaultAction;
		}
		
		return result.intern();
	}
	
	public DockAction getDockAction( int index ){
		if( index != 0 )
			throw new IllegalArgumentException( "only index=0 supported" );
		
		return currentAction();
	}

	public int getDockActionCount(){
		if( currentAction() != null )
			return 1;
		else
			return 0;
	}

	public LocationHint getLocationHint(){
		return hint;
	}

	public Iterator iterator(){
		return new Iterator(){
			private DockAction action = currentAction();
			
			public boolean hasNext(){
				return action != null;
			}
			
			public DockAction next(){
				if( action == null )
					throw new IllegalStateException( "no elements left" );
				DockAction result = action;
				action = null;
				return result;
			}
			
			public void remove(){
				throw new UnsupportedOperationException();	
			}
		};
	}
	
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy