/*
* 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.facile.menu;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import javax.swing.JMenu;
import bibliothek.gui.dock.support.menu.MenuPiece;
import bibliothek.gui.dock.support.menu.MenuPieceListener;
/**
* The root of a tree of {@link MenuPiece}s. This {@link MenuPiece} is a direct representation
* of a {@link JMenu}
* @author Benjamin Sigg
*/
public class RootMenuPiece extends NodeMenuPiece {
/** the menu into which this piece will insert its content */
private JMenu menu;
/** disable {@link #menu} when there are no items */
private boolean disableWhenEmpty;
/** whether the {@link #menu} should be enabled */
private boolean enabled = true;
/**
* Creates a new root-piece, using a normal {@link JMenu} to inserts
* its content.
*/
public RootMenuPiece(){
this( new JMenu() );
}
/**
* Creates a new root-piece, using a normal {@link JMenu}.
* @param text the text of the menu
* @param disableWhenEmpty whether to disable the menu when it is empty
* @param pieces the elements of this piece
*/
public RootMenuPiece( String text, boolean disableWhenEmpty, MenuPiece... pieces ){
this( new JMenu( text ));
setDisableWhenEmpty( disableWhenEmpty );
for( MenuPiece piece : pieces )
add( piece );
}
/**
* Creates a new root-piece.
* @param menu the menu into which this piece will insert its content
*/
public RootMenuPiece( JMenu menu ){
if( menu == null )
throw new NullPointerException( "menu must not be null" );
this.menu = menu;
menu.addHierarchyListener( new HierarchyListener(){
public void hierarchyChanged( HierarchyEvent e ){
if( (e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 ){
EventQueue.invokeLater( new Runnable(){
public void run(){
checkVisibility();
}
} );
}
}
});
checkVisibility();
addListener( new MenuPieceListener(){
public void insert( MenuPiece child, int index, Component... items ){
JMenu menu = getMenu();
for( int i = 0; i < items.length; i++ )
menu.add( items[i], i+index );
updateEnabled();
}
public void remove( MenuPiece child, int index, int length ){
JMenu menu = getMenu();
for( int i = index+length-1; i >= index; i-- )
menu.remove( i );
updateEnabled();
}
});
}
/**
* Calls {@link JMenu#setEnabled(boolean)} with a parameter that is calculated using
* {@link #isDisableWhenEmpty()}, {@link #getItemCount()} and
*/
protected void updateEnabled(){
if( isEnabled() ){
if( isDisableWhenEmpty() ){
menu.setEnabled( getItemCount() > 0 );
}
else{
menu.setEnabled( true );
}
}
else{
menu.setEnabled( false );
}
}
private void checkVisibility(){
boolean showing;
if( getParent() == null ){
showing = menu.isShowing();
}
else{
showing = getParent().isBound();
}
if( showing && !isBound() ){
bind();
}
else if( !showing && isBound() ){
unbind();
}
}
/**
* Disables the menu if there are no items in the menu.
* @param disableWhenEmpty <code>true</code> if the menu should be
* disabled when empty
*/
public void setDisableWhenEmpty( boolean disableWhenEmpty ) {
this.disableWhenEmpty = disableWhenEmpty;
updateEnabled();
}
/**
* Whether to disable the menu when it is empty or not.
* @return <code>true</code> if the menu gets disabled
* @see #setEnabled(boolean)
*/
public boolean isDisableWhenEmpty() {
return disableWhenEmpty;
}
/**
* Enables or disables the menu. If the argument is <code>false</code>, then the
* menu is disabled in any case. Otherwise the menu may be enabled or disabled
* depending on the value of {@link #isDisableWhenEmpty()}.
* @param enabled wether the menu should be enabled
* @see #setEnabled(boolean)
*/
public void setEnabled( boolean enabled ) {
this.enabled = enabled;
updateEnabled();
}
/**
* Tells whether the menu can be enabled or not.
* @return <code>true</code> if the menu can be enabled
*/
public boolean isEnabled() {
return enabled;
}
@Override
public JMenu getMenu(){
return menu;
}
@Override
public void setParent( MenuPiece parent ){
super.setParent( parent );
checkVisibility();
}
}