/* * 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 * benjamin_sigg@gmx.ch * CH - Switzerland */ package bibliothek.gui.dock.action.actions; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.swing.Icon; import bibliothek.gui.Dockable; import bibliothek.gui.dock.action.ActionContentModifier; import bibliothek.gui.dock.action.ActionType; import bibliothek.gui.dock.action.DockAction; import bibliothek.gui.dock.action.SelectableDockAction; import bibliothek.gui.dock.action.view.ActionViewConverter; import bibliothek.gui.dock.action.view.ViewTarget; import bibliothek.gui.dock.disable.DisablingStrategy; import bibliothek.gui.dock.event.SelectableDockActionListener; /** * A {@link DockAction} that has a state <code>selected</code>. That state * has always the same value for every {@link Dockable} using this action. * @author Benjamin Sigg */ public abstract class SimpleSelectableAction extends SimpleDropDownItemAction implements SharingSelectableDockAction, SelectableDockAction{ /** observers of this action */ private List<SelectableDockActionListener> listeners = new ArrayList<SelectableDockActionListener>(); /** whether this action is selected or not */ private boolean selected = false; /** icons to be used if this action is selected */ private Map<ActionContentModifier, Icon> selectIcons = new HashMap<ActionContentModifier, Icon>(); /** how this action should be visualized */ private ActionType<SelectableDockAction> type; /** * A {@link SimpleSelectableAction} that is visualized as * a {@link ActionType#CHECK}. * @author Benjamin Sigg */ public static class Check extends SimpleSelectableAction{ /** * Creates the new action */ public Check(){ this( true ); } /** * Creates a new action * @param monitorDisabling whether the current {@link DisablingStrategy} should be monitored */ public Check( boolean monitorDisabling ){ super( ActionType.CHECK, monitorDisabling ); setDropDownSelectable( false ); } public boolean trigger( Dockable dockable ) { if( !isEnabled( dockable )) return false; setSelected( dockable, !isSelected( dockable ) ); return true; } }; /** * A {@link SimpleSelectableAction} that is visualized as * a {@link ActionType#RADIO}. * @author Benjamin Sigg */ public static class Radio extends SimpleSelectableAction{ /** * Creates the new action */ public Radio(){ this( true ); } /** * Creates a new action * @param monitorDisabling whether the current {@link DisablingStrategy} should be monitored */ public Radio( boolean monitorDisabling ){ super( ActionType.RADIO, monitorDisabling ); setDropDownTriggerableSelected( false ); } public boolean trigger( Dockable dockable ) { if( !isEnabled( dockable ) || isSelected( dockable )) return false; setSelected( dockable, true ); return true; } } /** * Creates a new action. * @param type how this action is to be visualized * @param monitorDisabling whether the current {@link DisablingStrategy} should be monitored */ public SimpleSelectableAction( ActionType<SelectableDockAction> type, boolean monitorDisabling ){ super( monitorDisabling ); if( type == null ) throw new IllegalArgumentException( "Type must not be null" ); this.type = type; } public <V> V createView( ViewTarget<V> target, ActionViewConverter converter, Dockable dockable ){ return converter.createView( type, this, target, dockable ); } public void addSelectableListener( SelectableDockActionListener listener ){ listeners.add( listener ); } public void removeSelectableListener( SelectableDockActionListener listener ){ listeners.remove( listener ); } /** * Fires an event to all observers of type {@link SelectableDockActionListener}. */ protected void fireSelectedChanged(){ Set<Dockable> dockables = getBoundDockables(); for( SelectableDockActionListener listener : listeners.toArray( new SelectableDockActionListener[ listeners.size() ] )) listener.selectedChanged( this, dockables ); } public boolean isSelected( Dockable dockable ){ return selected; } public void setSelected( Dockable dockable, boolean selected ){ setSelected( selected ); } public boolean isSelected() { return selected; } public void setSelected( boolean selected ){ if( selected != this.selected ){ this.selected = selected; fireSelectedChanged(); fireActionIconChanged( null, getBoundDockables() ); } } @Override public Icon getIcon( Dockable dockable, ActionContentModifier modifier ){ if( isSelected() ) return firstNonNull( selectIcons.get( modifier ), super.getIcon( dockable, modifier ) ); else return super.getIcon( dockable, modifier ); } /** * Gets the first element of <code>icons</code> that is not <code>null</code>. * @param icons a list of icons * @return the first non-null icon */ protected Icon firstNonNull( Icon...icons ){ for( Icon icon : icons ) if( icon != null ) return icon; return null; } @Override public ActionContentModifier[] getIconContexts( Dockable dockable ){ Set<ActionContentModifier> result = new HashSet<ActionContentModifier>(); for( ActionContentModifier modifier : super.getIconContexts( dockable )){ result.add( modifier ); } result.addAll( selectIcons.keySet() ); return result.toArray( new ActionContentModifier[ result.size() ] ); } /** * Sets the icon which is shown if this action is selected * @param icon the icon to show, or <code>null</code> */ public void setSelectedIcon( Icon icon ){ setSelectedIcon( ActionContentModifier.NONE, icon ); } /** * Gets the icon which is shown if this action is selected * @return the icon or <code>null</code> */ public Icon getSelectedIcon(){ return getSelectedIcon( ActionContentModifier.NONE ); } /** * Sets the icon which is shown if this action is selected but disabled * @param icon the icon to show, or <code>null</code> */ public void setDisabledSelectedIcon( Icon icon ){ setSelectedIcon( ActionContentModifier.DISABLED, icon ); } /** * Gets the icon which is shown if this action is selected but disabled * @return the icon or <code>null</code> */ public Icon getDisabledSelectedIcon(){ return getSelectedIcon( ActionContentModifier.DISABLED ); } public Icon getSelectedIcon( ActionContentModifier modifier ){ return selectIcons.get( modifier ); } public void setSelectedIcon( ActionContentModifier modifier, Icon selectedIcon ){ if( selectedIcon == null ){ selectIcons.remove( modifier ); } else{ selectIcons.put( modifier, selectedIcon ); } fireActionIconChanged( modifier, getBoundDockables() ); } }