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

org.pushingpixels.flamingo.api.common.popup.JCommandPopupMenu Maven / Gradle / Ivy

/*
 * Copyright (c) 2005-2010 Flamingo Kirill Grouchnikov. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 * 
 *  o Redistributions of source code must retain the above copyright notice, 
 *    this list of conditions and the following disclaimer. 
 *     
 *  o Redistributions in binary form must reproduce the above copyright notice, 
 *    this list of conditions and the following disclaimer in the documentation 
 *    and/or other materials provided with the distribution. 
 *     
 *  o Neither the name of Flamingo Kirill Grouchnikov nor the names of 
 *    its contributors may be used to endorse or promote products derived 
 *    from this software without specific prior written permission. 
 *     
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */
package org.pushingpixels.flamingo.api.common.popup;

import java.awt.Component;
import java.util.ArrayList;
import java.util.Collections;

import javax.swing.*;
import javax.swing.JPopupMenu.Separator;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.pushingpixels.flamingo.api.common.*;
import org.pushingpixels.flamingo.internal.ui.common.popup.BasicCommandPopupMenuUI;
import org.pushingpixels.flamingo.internal.ui.common.popup.PopupPanelUI;

/**
 * Popup menu. Can host any number of command menu buttons added with
 * {@link #addMenuButton(JCommandMenuButton)} separated with optional
 * {@link #addMenuSeparator()}. The
 * {@link #JCommandPopupMenu(JCommandButtonPanel, int, int)} constructor allows
 * placing a scrollable command button panel in the top part of the popup menu.
 * 
 * @author Kirill Grouchnikov
 */
public class JCommandPopupMenu extends JPopupPanel {
	/**
	 * @see #getUIClassID
	 */
	public static final String uiClassID = "CommandPopupMenuUI";

	/**
	 * The main button panel. Can be null if this command popup
	 * menu was created with the {@link #JCommandPopupMenu()} constructor.
	 * 
	 * @see #JCommandPopupMenu(JCommandButtonPanel, int, int)
	 * @see #hasCommandButtonPanel()
	 * @see #getMainButtonPanel()
	 */
	protected JCommandButtonPanel mainButtonPanel;

	/**
	 * Menu components. This list holds:
	 * 
    *
  • {@link JCommandMenuButton}s added with * {@link #addMenuButton(JCommandMenuButton)}
  • *
  • {@link JCommandToggleMenuButton}s added with * {@link #addMenuButton(JCommandToggleMenuButton)}
  • *
  • {@link Separator}s added with {@link #addMenuSeparator()}
  • *
  • {@link JPanel}s added by the subclasses with * {@link #addMenuPanel(JPanel)}
  • *
* * @see #addMenuButton(JCommandMenuButton) * @see #addMenuButton(JCommandToggleMenuButton) * @see #addMenuSeparator() * @see #addMenuPanel(JPanel) * @see #getMenuComponents() */ protected java.util.List menuComponents; /** * Maximum number of button columns visible in the {@link #mainButtonPanel}. * * @see #JCommandPopupMenu(JCommandButtonPanel, int, int) * @see #getMaxButtonColumns() */ protected int maxButtonColumns; /** * Maximum number of button rows visible in the {@link #mainButtonPanel}. * * @see #JCommandPopupMenu(JCommandButtonPanel, int, int) * @see #getMaxVisibleButtonRows() */ protected int maxVisibleButtonRows; /** * Maximum number of menu items visible in this menu. If more buttons are * added with the {@link #addMenuButton(JCommandMenuButton)} and * {@link #addMenuButton(JCommandToggleMenuButton)} APIs, the menu part will * show scroller buttons above the first and below the last menu button. If * the value is negative, there is no limitation on how many menu buttons * are shown, and the entire popup menu can overflow the monitor edges. */ protected int maxVisibleMenuButtons; private boolean toDismissOnChildClick; /** * Creates an empty popup menu with no button panel. */ public JCommandPopupMenu() { this.menuComponents = new ArrayList(); this.maxVisibleMenuButtons = -1; this.toDismissOnChildClick = true; } /** * Creates a popup menu hosting the specified button panel. * * @param buttonPanel * Fully constructed button panel. * @param maxButtonColumns * Maximum number of button columns visible in * buttonPanel. * @param maxVisibleButtonRows * Maximum number of button rows visible in * buttonPanel. */ public JCommandPopupMenu(JCommandButtonPanel buttonPanel, int maxButtonColumns, int maxVisibleButtonRows) { this(); this.mainButtonPanel = buttonPanel; this.maxButtonColumns = maxButtonColumns; this.maxVisibleButtonRows = maxVisibleButtonRows; this.updateUI(); } /** * Adds the specified menu button to this menu. * * @param menuButton * Menu button to add. */ public void addMenuButton(JCommandMenuButton menuButton) { menuButton.setHorizontalAlignment(SwingUtilities.LEFT); this.menuComponents.add(menuButton); this.fireStateChanged(); } /** * Adds the specified toggle menu button to this menu. * * @param menuButton * Menu button to add. */ public void addMenuButton(JCommandToggleMenuButton menuButton) { menuButton.setHorizontalAlignment(SwingUtilities.LEFT); this.menuComponents.add(menuButton); this.fireStateChanged(); } /** * Adds a menu separator to this menu. */ public void addMenuSeparator() { this.menuComponents.add(new JPopupMenu.Separator()); this.fireStateChanged(); } /** * Adds a menu panel to this menu. * * @param menuPanel * Menu panel to add. */ protected void addMenuPanel(JPanel menuPanel) { if (this.maxVisibleMenuButtons > 0) { throw new IllegalStateException( "This method is not supported on menu that contains a command button panel"); } this.menuComponents.add(menuPanel); this.fireStateChanged(); } /** * Returns indication whether this menu has a command button panel. * * @return true if this menu has a command button panel, * false otherwise. * @see #getMainButtonPanel() */ public boolean hasCommandButtonPanel() { return (this.mainButtonPanel != null); } /** * Returns the command button panel of this menu. Can return * null. * * @return The command button panel of this menu. * @see #hasCommandButtonPanel() */ public JCommandButtonPanel getMainButtonPanel() { return this.mainButtonPanel; } /** * Returns an unmodifiable list of all the menu components. Can return * null. * * @return An unmodifiable list of all the menu components */ public java.util.List getMenuComponents() { if (this.menuComponents == null) return null; return Collections.unmodifiableList(this.menuComponents); } /** * Returns the maximum number of button columns visible in the command * button panel of this menu. If this menu has been created with the * {@link #JCommandPopupMenu()} constructor, zero is returned. * * @return The maximum number of button columns visible in the command * button panel of this menu. * @see #JCommandPopupMenu(JCommandButtonPanel, int, int) * @see #getMaxVisibleButtonRows() */ public int getMaxButtonColumns() { return this.maxButtonColumns; } /** * Returns the maximum number of button rows visible in the command button * panel of this menu. If this menu has been created with the * {@link #JCommandPopupMenu()} constructor, zero is returned. * * @return The maximum number of button rows visible in the command button * panel of this menu. * @see #JCommandPopupMenu(JCommandButtonPanel, int, int) * @see #getMaxButtonColumns() */ public int getMaxVisibleButtonRows() { return this.maxVisibleButtonRows; } /** * Returns the maximum number of menu items visible in this menu. * * @return The maximum number of menu items visible in this menu. If the * value is negative, there is no limitation on how many menu * buttons are shown, and the entire popup menu can overflow the * monitor edges. */ public int getMaxVisibleMenuButtons() { return this.maxVisibleMenuButtons; } /** * Sets the maximum number of menu items visible in this menu. If the value * is negative, there is no limitation on how many menu buttons are shown, * and the entire popup menu can overflow the monitor edges. * * @param maxVisibleMenuButtons * The new value for the maximum number of menu items visible in * this menu. */ public void setMaxVisibleMenuButtons(int maxVisibleMenuButtons) { for (Component menuComp : this.menuComponents) { if (menuComp instanceof JPanel) { throw new IllegalStateException( "This method is not supported on menus with panels"); } } int old = this.maxVisibleMenuButtons; this.maxVisibleMenuButtons = maxVisibleMenuButtons; if (old != this.maxVisibleMenuButtons) { this.firePropertyChange("maxVisibleMenuButtons", old, this.maxVisibleMenuButtons); } } @Override public String getUIClassID() { return uiClassID; } @Override public void updateUI() { if (UIManager.get(getUIClassID()) != null) { setUI((PopupPanelUI) UIManager.getUI(this)); } else { setUI(BasicCommandPopupMenuUI.createUI(this)); } } /** * Adds the specified change listener to track changes to this popup menu. * * @param l * Change listener to add. * @see #removeChangeListener(ChangeListener) */ public void addChangeListener(ChangeListener l) { this.listenerList.add(ChangeListener.class, l); } /** * Removes the specified change listener from tracking changes to this popup * menu. * * @param l * Change listener to remove. * @see #addChangeListener(ChangeListener) */ public void removeChangeListener(ChangeListener l) { this.listenerList.remove(ChangeListener.class, l); } /** * Notifies all registered listener that the state of this popup menu has * changed. */ protected void fireStateChanged() { // Guaranteed to return a non-null array Object[] listeners = this.listenerList.getListenerList(); // Process the listeners last to first, notifying // those that are interested in this event ChangeEvent event = new ChangeEvent(this); for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == ChangeListener.class) { ((ChangeListener) listeners[i + 1]).stateChanged(event); } } } public boolean isToDismissOnChildClick() { return toDismissOnChildClick; } public void setToDismissOnChildClick(boolean toDismissOnChildClick) { this.toDismissOnChildClick = toDismissOnChildClick; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy