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

bibliothek.gui.dock.control.PopupController Maven / Gradle / Ivy

The 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) 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
 * [email protected]
 * CH - Switzerland
 */
package bibliothek.gui.dock.control;

import java.awt.Component;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.Map;

import javax.swing.SwingUtilities;

import bibliothek.gui.DockController;
import bibliothek.gui.Dockable;
import bibliothek.gui.dock.DockElementRepresentative;
import bibliothek.gui.dock.action.ActionPopup;
import bibliothek.gui.dock.action.ActionPopupSuppressor;
import bibliothek.gui.dock.action.DockAction;
import bibliothek.gui.dock.action.DockActionSource;
import bibliothek.gui.dock.action.popup.DefaultActionPopupMenuFactory;
import bibliothek.gui.dock.action.popup.ActionPopupMenuFactory;
import bibliothek.gui.dock.event.DockControllerRepresentativeListener;

/**
 * Manages the popup menus, adds a listeners to all {@link DockElementRepresentative}s to open popup menus
 * when the user makes a right click.
 * @author Benjamin Sigg
 */
public class PopupController implements DockControllerRepresentativeListener{
    /** tells which Dockable has which listener */
    private Map listeners =
        new HashMap();
    
    /** the controller for which this popup-controller works */
    private DockController controller;
    
    /** this factory creates the menus that are popping up */
    private ActionPopupMenuFactory factory = new DefaultActionPopupMenuFactory();
    
    /** tells which popups are to be shown */
    private ActionPopupSuppressor popupSuppressor = ActionPopupSuppressor.ALLOW_ALWAYS;
    
    /** if set, then popup menus may be opened during drag and drop operations */
    private boolean allowOnMove = false;
    
    /** if set, then empty menus can be opened */
    private boolean allowEmpty = false;
    
    /**
     * Creates a new popup-controller.
     * @param controller the controller for which this instance works
     */
    public PopupController( DockController controller ){
    	if( controller == null )
    		throw new IllegalArgumentException( "controller must not be null" );
    	
    	this.controller = controller;
    	controller.addRepresentativeListener( this );
    }
    
    public void representativeAdded( DockController controller, DockElementRepresentative representative ) {
        if( representative.getElement().asDockable() != null ){
            ComponentObserver observer = new ComponentObserver( representative );
            listeners.put( representative, observer );
            representative.addMouseInputListener( observer );
        }
    }
    
    public void representativeRemoved( DockController controller, DockElementRepresentative representative ) {
        if( representative.getElement().asDockable() != null ){
            ComponentObserver observer = listeners.remove( representative );
            if( observer != null ){
                representative.removeMouseInputListener( observer );
            }
        }
    }
    
    /**
     * Gets the {@link DockController} for which this {@link PopupController} works.
     * @return the owner of this controller
     */
    public DockController getController(){
		return controller;
	}
    
    /**
     * Sets the factoy which creates new menus that pop up.
     * @param factory the factory creating menus, not null
     */
    public void setPopupMenuFactory( ActionPopupMenuFactory factory ){
    	if( factory == null ){
    		throw new IllegalArgumentException( "the factory must not be null" );
    	}
    	this.factory = factory;
    }
    
    /**
     * Gets the factory which is responsible for creating new menus.
     * @return the factory, never null
     */
    public ActionPopupMenuFactory getPopupMenuFactory(){
		return factory;
	}

    /**
     * Gets the guard which decides, which popups should be allowed.
     * @return the guard
     * @see #setPopupSuppressor(ActionPopupSuppressor)
     */
    public ActionPopupSuppressor getPopupSuppressor() {
        return popupSuppressor;
    }
    
    /**
     * Sets the guard which decides, which popups with {@link DockAction DockActions}
     * are allowed to show up, and which popups will be suppressed.
     * @param popupSuppressor the guard
     */
    public void setPopupSuppressor( ActionPopupSuppressor popupSuppressor ) {
        if( popupSuppressor == null )
            throw new IllegalArgumentException( "suppressor must not be null" );
        this.popupSuppressor = popupSuppressor;
    }
    
    /**
     * If set, then empty menus are still opened. The {@link ActionPopupSuppressor} or the
     * {@link ActionPopupMenuFactory} may however catch the empty menu and hide it.
     * @param allowEmpty if set to false, empty menus can never be shown
     */
    public void setAllowEmptyMenu( boolean allowEmpty ){
		this.allowEmpty = allowEmpty;
	}
    
    /**
     * Tells whether empty menus can be shown.
     * @return true if empty menus can be shown
     */
    public boolean isAllowEmptyMenu(){
		return allowEmpty;
	}
    
    /**
     * Sets whether menus can be opened during drag and drop operations. This property should
     * be remain false and only be set to true for very special occasions.
     * @param allowOnMove whether menus can be opened during drag and drop operations
     */
    public void setAllowOnMove( boolean allowOnMove ){
		this.allowOnMove = allowOnMove;
	}
    
    /**
     * Tells whether menus can be opened during drag and drop operations
     * @return true if menus can be opened all the time
     */
    public boolean isAllowOnMove(){
		return allowOnMove;
	}
    
    /**
     * A mouse listener opening a popup menu when necessary.
     * @author Benjamin Sigg
     */
    private static class ComponentObserver extends ActionPopup{
        /** the representation of the element for which this might open a popup */
    	private DockElementRepresentative representative;
        
    	/** whether currently the mouse gets clicked */
    	private boolean onMouseClick = false;
    	
    	/**
    	 * Creates a new observer
    	 * @param representative the element which represents the {@link Dockable}
    	 * of this observer
    	 */
    	public ComponentObserver( DockElementRepresentative representative ){
    		super( true );
    		this.representative = representative;
    	}
    	
    	@Override
    	public void mouseClicked( MouseEvent e ){
    	    if( isMenuOpen() )
    	        return;
    	    
    		if( isEnabled() && e.getClickCount() == 1 ){
    		    try{
    		        onMouseClick = true;
    		        popup( e.getComponent(), e.getX(), e.getY() );
    		    }
    		    finally{
    		        onMouseClick = false;
    		    }
    		}
    	}
    	
    	@Override
    	protected Point getPopupLocation( Component owner, Point location ) {
    	    location = new Point( location );
    	    location = SwingUtilities.convertPoint( owner, location, representative.getComponent() );
    	    location = representative.getPopupLocation( location, !onMouseClick );
    	    if( location == null )
    	        return null;
    	    else
    	        location = new Point( location );
    	    return SwingUtilities.convertPoint( representative.getComponent(), location, owner );
    	}
    	
        @Override
        protected Dockable getDockable() {
            return representative.getElement().asDockable();
        }

        @Override
        protected DockActionSource getActions() {
            return getDockable().getGlobalActionOffers();
        }
        
        @Override
        protected Object getSource(){
	        return representative;
        }

        @Override
        protected boolean isEnabled() {
            return true;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy