Package bibliothek.gui.dock.common.action

Source Code of bibliothek.gui.dock.common.action.CPanelPopup$PanelPopup

/*
* 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) 2009 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.action;

import java.awt.Component;
import java.awt.Point;

import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JMenu;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;

import bibliothek.gui.Dockable;
import bibliothek.gui.dock.action.ActionType;
import bibliothek.gui.dock.action.view.ActionViewConverter;
import bibliothek.gui.dock.action.view.ViewTarget;
import bibliothek.gui.dock.common.action.core.CommonSimpleButtonAction;
import bibliothek.gui.dock.common.action.panel.DialogWindow;
import bibliothek.gui.dock.common.action.panel.MenuWindow;
import bibliothek.gui.dock.common.action.panel.PanelPopupWindow;
import bibliothek.gui.dock.common.action.panel.PanelPopupWindowListener;
import bibliothek.gui.dock.common.intern.action.CDecorateableAction;
import bibliothek.gui.dock.title.DockTitle;
import bibliothek.gui.dock.title.DockTitle.Orientation;

/**
* This action shows some kind of popup (for example a {@link JDialog}) filled
* with any content the client likes. This action is intended to be shown
* as button in a title, but can also be used as menu item in a menu.<br>
* Clients may override the various <code>onXYZ</code>-methods and create
* and show their custom popup. In such a case they should call {@link #openPopup(PanelPopupWindow)}
* to ensure that only one window is open at a time.<br>
* As long as the user works on the popup-window it does not close automatically,
* clients can call {@link #closePopup()} to explicitly close it. The
* window closes automatically if it loses the focus, clients can call
* {@link #setCloseOnFocusLost(boolean)} to change that behavior.
* <br>
* <b>Note:</b> this action does not support being child of a drop down menu
* @author Benjamin Sigg
*/
public class CPanelPopup extends CDecorateableAction<CPanelPopup.PanelPopup>{
  /** the kind of action this class represents */
  public static final ActionType<CPanelPopup.PanelPopup> PANEL_POPUP =
    new ActionType<PanelPopup>( "panel popup" );
 
  /**
   * Tells how a {@link CPanelPopup} behaves if it is a child
   * of a menu.
   * @author Benjamin Sigg
   */
  public static enum MenuBehavior{
    /** the action remains invisible */
    HIDE,
   
    /** the action pushes the custom component on a {@link JMenu} */
    SUBMENU,
   
    /** the action shows an undecorated dialog if triggered */
    UNDECORATED_DIALOG,
   
    /** the action shows a decorated dialog if triggered */
    DECORATED_DIALOG
  }
 
  /**
   * When the popup should show up if the action is displayed as button.
   * @author Benjamin Sigg
   */
  public static enum ButtonBehavior{
    /** the popup shows up if the mouse is pressed */
    OPEN_ON_PRESS,
   
    /** the popup shows up if the mouse is released */
    OPEN_ON_CLICK
  }
 
  /** how to handle the case where this action is child of a menu */
  private MenuBehavior menu = MenuBehavior.UNDECORATED_DIALOG;
 
  /** when to show the popup */
  private ButtonBehavior button = ButtonBehavior.OPEN_ON_CLICK;
 
  /** the content of this {@link CPanelPopup} */
  private JComponent content;
 
  /** current open window */
  private PanelPopupWindow window;
 
  /** whether the window is closed automatically if focus is lost */
  private boolean closeOnFocusLost = true;
 
  /** a listener to {@link #window} */
  private PanelPopupWindowListener listener = new PanelPopupWindowListener(){
    public void closed( PanelPopupWindow window ){
      window.removeListener( listener );
      window = null;
    }
  };
 
  /**
   * Creates a new action.
   */
  public CPanelPopup(){
    super( null );
    init( new PanelPopup() );
  }
 
  /**
   * Sets the component that is shown on a popup dialog/menu/window... by
   * this {@link CPanelPopup}.
   * @param content the content, may be <code>null</code>
   */
  public void setContent( JComponent content ){
    this.content = content;
  }
 
  /**
   * Gets the contents of this action.
   * @return the contents
   */
  public JComponent getContent(){
    return content;
  }
 
  /**
   * Tells this action how to behave if it is in a menu. This may not have an effect
   * if the action already is part of a menu.
   * @param menu the behavior, not <code>null</code>
   */
  public void setMenuBehavior( MenuBehavior menu ){
    if( menu == null )
      throw new IllegalArgumentException( "menu must not be null" );
    this.menu = menu;
  }
 
  /**
   * Tells how this action behaves if in a menu.
   * @return the behavior, not <code>null</code>
   */
  public MenuBehavior getMenuBehavior(){
    return menu;
  }
 
  /**
   * Tells this action how to handle buttons.
   * @param button when to open a popup
   */
  public void setButtonBehavior( ButtonBehavior button ){
    if( button == null )
      throw new IllegalArgumentException( "button must not be null" );
    this.button = button;
  }
 
  /**
   * Tells how this action behaves if displayed as button.
   * @return the behavior, not <code>null</code>
   */
  public ButtonBehavior getButtonBehavior(){
    return button;
  }
 
  /**
   * Whether the window should be closed if focus is lost.
   * @param closeOnFocusLost <code>true</code> if it should close automatically
   */
  public void setCloseOnFocusLost( boolean closeOnFocusLost ){
    this.closeOnFocusLost = closeOnFocusLost;
  }
 
  /**
   * Tells whether the window is automatically closed if the focus is lost.
   * @return whether the popup is closed automatically
   */
  public boolean isCloseOnFocusLost(){
    return closeOnFocusLost;
  }
 
  /**
   * Informs this {@link CPanelPopup} that its content is shown and
   * allows this to handle the closing event.
   * @param window the window
   * @throws IllegalArgumentException if {@link PanelPopupWindow#isOpen()}
   * return <code>false</code>
   */
  public void openPopup( PanelPopupWindow window ){
    if( !window.isOpen() ){
      throw new IllegalArgumentException( "window is not open" );
    }
   
    closePopup();
   
    this.window = window;
    this.window.addListener( listener );
  }
 
  /**
   * Makes the current popup invisible.
   */
  public void closePopup(){
    if( window != null ){
      window.close();
    }
  }
 
  /**
   * Tells whether the content of this action is currently being showed.
   * @return <code>true</code> if the content is visible
   */
  public boolean isOpen(){
    return window != null && window.isOpen();
  }
 
  /**
   * Called if the mouse is pressed on the button <code>item</code> of
   * of a {@link DockTitle} which has orientation <code>orientation</code>.
   * @param item the pressed component
   * @param orientation the orientation of the title
   */
  protected void onMousePressed( JComponent item, Orientation orientation ){
    if( getButtonBehavior() == ButtonBehavior.OPEN_ON_PRESS ){
      openDialog( item, orientation );
    }
  }

  /**
   * Called if the mouse is released of the button <code>item</code> of
   * of a {@link DockTitle} which has orientation <code>orientation</code>.
   * @param item the released component
   * @param orientation the orientation of the title
   */
  protected void onMouseReleased( JComponent item, Orientation orientation ){
    if( getButtonBehavior() == ButtonBehavior.OPEN_ON_CLICK ){
      openDialog( item, orientation );
    }
  }

  /**
   * Called if the button <code>item</code> of a {@link DockTitle} which has
   * orientation <code>orientation</code> was triggered.
   * @param item the triggered button
   * @param orientation the orientation of the title
   */
  protected void onTrigger( JComponent item, Orientation orientation ){
    openDialog( item, orientation );
 
 
  /**
   * Opens a new undecorated dialog below or aside of <code>item</code>. This method
   * does nothing if {@link #isOpen()} return <code>true</code>.
   * @param item the owner of the new dialog
   * @param orientation the orientation of the title which shows <code>item</code>
   */
  protected void openDialog( JComponent item, Orientation orientation ){
    if( isOpen() || content == null )
      return;
   
    Point location = new Point();
    if( orientation.isHorizontal() ){
      location.y = item.getHeight();
    }
    else{
      location.x = item.getWidth();
    }
   
    SwingUtilities.convertPointToScreen( location, item );
   
    DialogWindow window = createDialogWindow( item );
    window.setUndecorated( true );
    window.setContent( getContent() );
    window.open( location.x, location.y );
   
    openPopup( window );
  }
 
  /**
   * Called if the menu-item representing this action has been
   * hit.
   * @param dockable the source of the event
   */
  protected void onMenuItemTrigger( Dockable dockable ){
    if( content == null )
      return;
   
    closePopup();
   
    DialogWindow window = createDialogWindow( dockable.getComponent() );
    window.setUndecorated( getMenuBehavior() == MenuBehavior.UNDECORATED_DIALOG );
    window.setContent( getContent() );
    window.open( dockable.getComponent() );
   
    openPopup( window );
  }
 
  /**
   * Creates a new window which will be used as popup for this {@link CPanelPopup}.
   * @param owner the owner of the window
   * @return the new window, not <code>null</code>
   */
  protected DialogWindow createDialogWindow( Component owner ){
    return new DialogWindow( owner, this );
  }
 
  /**
   * Called if a menu is opening a submenu in which {@link #getContent() the content}
   * is to be shown.
   * @param menu the new parent of the content
   */
  protected void onMenuTrigger( JPopupMenu menu ){
    if( content == null )
      return;
   
    menu.add( content );
    MenuWindow window = createMenuWindow( menu );
    openPopup( window );
  }
 
  /**
   * Creates a new window which will be used as popup for this {@link CPanelPopup}.
   * @param menu the owner of the window
   * @return the new window, not <code>null</code>
   */
  protected MenuWindow createMenuWindow( JPopupMenu menu ){
    return new MenuWindow( menu );
  }
 
  /**
   * A custom action shows some dialog or window when triggered
   * @author Benjamin Sigg
   *
   */
  public class PanelPopup extends CommonSimpleButtonAction{
    /**
     * Creates a new action
     */
    public PanelPopup(){
      super( CPanelPopup.this );
    }
   
    public <V> V createView( ViewTarget<V> target, ActionViewConverter converter, Dockable dockable ){
      return converter.createView( PANEL_POPUP, this, target, dockable );
    }

    public boolean trigger( Dockable dockable ){
      return false;
    }
   
    /**
     * Gets the {@link CAction} that is represented by this action.
     * @return the action, never <code>null</code>
     */
    public CPanelPopup getAction(){
      return CPanelPopup.this;
    }
   
    /**
     * Called if the mouse is pressed on the button <code>item</code> of
     * of a {@link DockTitle} which has orientation <code>orientation</code>.
     * @param item the pressed component
     * @param orientation the orientation of the title
     */
    public void onMousePressed( JComponent item, Orientation orientation ){
      CPanelPopup.this.onMousePressed( item, orientation );
    }

    /**
     * Called if the mouse is released of the button <code>item</code> of
     * of a {@link DockTitle} which has orientation <code>orientation</code>.
     * @param item the released component
     * @param orientation the orientation of the title
     */
    public void onMouseReleased( JComponent item, Orientation orientation ){
      CPanelPopup.this.onMouseReleased( item, orientation );
    }

    /**
     * Called if the button <code>item</code> of a {@link DockTitle} which has
     * orientation <code>orientation</code> was triggered.
     * @param item the triggered button
     * @param orientation the orientation of the title
     */
    public void onTrigger( JComponent item, Orientation orientation ){
      CPanelPopup.this.onTrigger( item, orientation );
    }
   
    /**
     * Called if the menu-item representing this action has been
     * hit.
     * @param dockable the source of the event
     */
    public void onMenuItemTrigger( Dockable dockable ){
      CPanelPopup.this.onMenuItemTrigger( dockable );
    }
   
    /**
     * Called if a menu is opening a submenu in which {@link #getContent() the content}
     * is to be shown.
     * @param menu the new parent of the content
     */
    public void onMenuTrigger( JPopupMenu menu ){
      CPanelPopup.this.onMenuTrigger( menu );
    }
  }
}
TOP

Related Classes of bibliothek.gui.dock.common.action.CPanelPopup$PanelPopup

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.