/*
* 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.common.menu;
import bibliothek.gui.DockFrontend;
import bibliothek.gui.Dockable;
import bibliothek.gui.dock.common.CControl;
import bibliothek.gui.dock.common.event.CDockableAdapter;
import bibliothek.gui.dock.common.intern.CDockable;
import bibliothek.gui.dock.common.intern.CommonDockable;
import bibliothek.gui.dock.event.DockFrontendAdapter;
import bibliothek.gui.dock.facile.menu.CloseableDockableMenuPiece;
/**
* A piece of a menu that adds an item for each closeable {@link CDockable}
* that can be found in a {@link CControl}. The user can show or hide
* {@link CDockable}s by clicking onto these items.<br>
* <b>Please note: </b> this menu shows only {@link CDockable}s that really do exist,
* if a dockable is loaded lazy, then this menu does not show the element!
* @author Benjamin Sigg
*/
public class SingleCDockableListMenuPiece extends CloseableDockableMenuPiece {
/** the list of all {@link CDockable}s */
private CControl control;
/** a manager that ensures that those {@link CDockable}s which are closeable have an item in the menu */
private CloseableListenerManager closeableManager = new CloseableListenerManager();
/**
* Creates a new piece.
* @param control the control to observe for new {@link Dockable}s, can be <code>null</code>.
*/
public SingleCDockableListMenuPiece( CControl control ) {
setControl( control );
}
/**
* Exchanges the {@link CControl} whose {@link CDockable}s are observed
* by this piece.
* @param control the new control to observe, can be <code>null</code>
*/
public void setControl( CControl control ) {
if( this.control != control ){
this.control = control;
if( control == null ){
setFrontend( null );
}
else{
setFrontend( control.intern() );
}
}
}
@Override
public void bind(){
if( !isBound() ){
super.bind();
closeableManager.bind();
}
}
@Override
public void unbind(){
if( isBound() ){
super.unbind();
closeableManager.unbind();
}
}
@Override
public void setFrontend( DockFrontend frontend ) {
super.setFrontend( frontend );
closeableManager.setFrontend( frontend );
}
@Override
protected void show( Dockable dockable ) {
if( dockable instanceof CommonDockable )
((CommonDockable)dockable).getDockable().setVisible( true );
else
super.show( dockable );
}
@Override
protected void hide( Dockable dockable ) {
if( dockable instanceof CommonDockable )
((CommonDockable)dockable).getDockable().setVisible( false );
else
super.hide( dockable );
}
@Override
protected boolean include( Dockable dockable ) {
if( dockable instanceof CommonDockable )
return ((CommonDockable)dockable).getDockable().isCloseable();
return super.include( dockable );
}
/**
* A listener added to a {@link DockFrontend}, will add or remove
* the {@link CloseableListener} from {@link CDockable}s when they are
* added or removed to {@link #frontend}.
* @author Benjamin Sigg
*/
private class CloseableListenerManager extends DockFrontendAdapter{
/** the listener to add or remove */
private CloseableListener listener = new CloseableListener();
/** the frontend to observe */
private DockFrontend frontend;
/**
* Sets the frontend that will be observed for new or deleted
* {@link CDockable}s.
* @param frontend the new frontend, can be <code>null</code>
*/
public void setFrontend( DockFrontend frontend ) {
if( this.frontend != frontend ){
if( isBound() ){
if( this.frontend != null ){
this.frontend.removeFrontendListener( this );
for( Dockable dockable : frontend.listDockables() )
removed( this.frontend, dockable );
}
}
this.frontend = frontend;
if( isBound() ){
if( this.frontend != null ){
this.frontend.addFrontendListener( this );
for( Dockable dockable : frontend.listDockables() )
added( this.frontend, dockable );
}
}
}
}
/**
* Connects this listener with {@link #frontend}
*/
public void bind(){
if( this.frontend != null ){
frontend.addFrontendListener( this );
for( Dockable dockable : frontend.listDockables() )
added( frontend, dockable );
}
}
/**
* Disconnects this listener from {@link #frontend}
*/
public void unbind(){
if( frontend != null ){
frontend.removeFrontendListener( this );
for( Dockable dockable : frontend.listDockables() )
removed( frontend, dockable );
}
}
@Override
public void added( DockFrontend frontend, Dockable dockable ) {
if( dockable instanceof CommonDockable ){
((CommonDockable)dockable).getDockable().addCDockablePropertyListener( listener );
}
}
@Override
public void removed( DockFrontend frontend, Dockable dockable ) {
if( dockable instanceof CommonDockable ){
((CommonDockable)dockable).getDockable().removeCDockablePropertyListener( listener );
}
}
}
/**
* A listener waiting for the closeable-property to change, and then
* calling {@link SingleCDockableListMenuPiece#check(Dockable)}.
* @author Benjamin Sigg
*/
private class CloseableListener extends CDockableAdapter{
@Override
public void closeableChanged( CDockable dockable ) {
check( dockable.intern() );
}
}
}