/* * 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.control.focus; import java.awt.Component; import java.util.ArrayList; import java.util.List; import bibliothek.gui.DockController; import bibliothek.gui.Dockable; import bibliothek.gui.dock.event.DockableFocusEvent; import bibliothek.gui.dock.event.DockableFocusListener; import bibliothek.gui.dock.event.FocusVetoListener; import bibliothek.gui.dock.event.FocusVetoListener.FocusVeto; import bibliothek.gui.dock.title.DockTitle; /** * Abstract implementation of {@link FocusController} offering methods to * handle the listeners. * @author Benjamin Sigg */ public abstract class AbstractFocusController implements FocusController{ /** the owner of this focus controller */ private DockController controller; /** strategy that decides which {@link Component} to focus */ private FocusStrategy strategy; /** Listeners observing the focused {@link Dockable} */ private List<DockableFocusListener> dockableFocusListeners = new ArrayList<DockableFocusListener>(); /** A list of listeners which can cancel a call to the controller */ private List<FocusVetoListener> vetos = new ArrayList<FocusVetoListener>(); /** how often this focus controller was frozen */ private int frozen = 0; /** * Creates a new focus controller * @param controller the owner of this controller, not <code>null</code> */ public AbstractFocusController( DockController controller ){ this.controller = controller; } public void setStrategy( FocusStrategy strategy ){ if( this.strategy != strategy ){ if( this.strategy != null ){ this.strategy.unbind(); } this.strategy = strategy; if( strategy != null ){ strategy.bind(); } } } public FocusStrategy getStrategy(){ return strategy; } public void freezeFocus(){ frozen++; } public void meltFocus(){ frozen--; } /** * Tells whether this {@link FocusController} is temporarily frozen and should * not process any events. * @return <code>true</code> if disabled */ protected boolean isFrozen(){ return frozen > 0; } /** * Adds a listener to this controller which can cancel a call to * the {@link DockController}. * @param listener the new listener */ public void addVetoListener( FocusVetoListener listener ){ vetos.add( listener ); } /** * Removes a listener from this controller * @param listener the listener to remove */ public void removeVetoListener( FocusVetoListener listener ){ vetos.remove( listener ); } /** * Asks all {@link FocusVetoListener} through their method * {@link FocusVetoListener#vetoFocus(FocusController, DockTitle)} * whether they want cancel a call to the {@link DockController}. * @param title the title which is about to be focused * @return the first veto */ protected FocusVeto fireVetoTitle( DockTitle title ){ for( FocusVetoListener listener : vetos.toArray( new FocusVetoListener[ vetos.size() ] )){ FocusVeto veto = listener.vetoFocus( this, title ); if( veto != FocusVeto.NONE ) return veto; } return FocusVeto.NONE; } /** * Asks all {@link FocusVetoListener} through their method * {@link FocusVetoListener#vetoFocus(FocusController, Dockable)} * whether they want cancel a call to the {@link DockController}. * @param dockable the Dockable which is about to be focused * @return the first veto */ protected FocusVeto fireVetoDockable( Dockable dockable ){ for( FocusVetoListener listener : vetos.toArray( new FocusVetoListener[ vetos.size() ] )){ FocusVeto veto = listener.vetoFocus( this, dockable ); if( veto != FocusVeto.NONE ) return veto; } return FocusVeto.NONE; } public DockController getController(){ return controller; } /** * Adds a listener to this controller, the listener will be informed when * the focused {@link Dockable} changes. * @param listener the new listener */ public void addDockableFocusListener( DockableFocusListener listener ){ if( listener == null ) throw new NullPointerException( "listener must not be null" ); dockableFocusListeners.add( listener ); } /** * Removes a listener from this controller. * @param listener the listener to remove */ public void removeDockableFocusListener( DockableFocusListener listener ){ if( listener == null ) throw new NullPointerException( "listener must not be null" ); dockableFocusListeners.remove( listener ); } /** * Gets an array of currently registered {@link DockableFocusListener}s. * @return the modifiable array */ protected DockableFocusListener[] dockableFocusListeners(){ return dockableFocusListeners.toArray( new DockableFocusListener[ dockableFocusListeners.size() ] ); } /** * Informs all listeners that <code>dockable</code> has gained * the focus. * @param oldFocused the old owner of the focus, may be <code>null</code> * @param newFocused the owner of the focus, may be <code>null</code> */ protected void fireDockableFocused( Dockable oldFocused, Dockable newFocused ){ DockableFocusEvent event = new DockableFocusEvent( controller, oldFocused, newFocused ); for( DockableFocusListener listener : dockableFocusListeners() ) listener.dockableFocused( event ); } }