/*
* PopupStrip.java
* (FScape)
*
* Copyright (c) 2001-2016 Hanns Holger Rutz. All rights reserved.
*
* This software is published under the GNU General Public License v3+
*
*
* For further information, please contact Hanns Holger Rutz at
* contact@sciss.de
*/
package de.sciss.fscape.gui;
import javax.swing.*;
import java.awt.event.ActionListener;
import java.util.Hashtable;
/**
* Popmenu-Generator. Utilizes MenuStrip.createStrip() und MenuStrip.setItemLabelAndCut()!
* Bescheuerterweise kann MenuStrip selbst nicht von JPopupMenu abgeleitet werden,
* da ein MenuBar.add() dann nicht funktioniert... :-(
*/
public class PopupStrip
extends JPopupMenu {
// -------- private variables --------
protected Hashtable<String, JMenuItem> h; // Objects = Menus/Items, Keys = ActionCommands (z.B. "&ZUndo")
protected ActionListener listener;
// -------- public methods --------
// public boolean setItemEnabled( String menuItem, boolean enable );
// public static boolean setItemEnabled( MenuBar mb, String menuItem, boolean enable );
// public boolean setItemJLabel( String menuItem, String label );
// public static boolean setItemJLabel( MenuBar mb, String menuItem, String label );
// public JMenuItem getItem( String menuItem );
// public static JMenuItem getItem( MenuBar mb, String menuItem );
/**
* @param menuItems inneres Array: 1 String fuer normale Items, mehrere fuer SubMenus
* ( "&c"-Anfang fuer Shortcuts; "#"-Ende fuer JCheckBoxes )
* @param listener ActionListener, der die Menuwahlen verarbeiten soll
*/
public PopupStrip( String menuItems[][], ActionListener listener )
{
super();
h = new Hashtable<String, JMenuItem>();
this.listener = listener;
PopupStrip.createStrip( this, h, menuItems, listener );
}
/**
* JMenuItem waehlbar/ghosted-Status aendern
*
* @param menuItem ActionString des gewuenschten Items
* @param enable true (waehlbar) bzw. false (ghosted)
* @return false, wenn Item nicht gefunden wurde
*/
public boolean setItemEnabled( String menuItem, boolean enable )
{
JMenuItem mi = h.get( menuItem );
if( mi != null ) {
mi.setEnabled( enable );
}
return( mi != null );
}
/**
* JLabel eines JMenuItems setzen
*
* @param menuItem ActionString des gewuenschten Items
* @param label neuer String ggf. mit Shortcut; entspricht dem ActionCommand
* @return false, wenn Item nicht gefunden wurde
*/
public boolean setItemJLabel( String menuItem, String label )
{
JMenuItem mi = (JMenuItem) h.get( menuItem );
if( mi != null ) {
h.remove( menuItem ); // alter Key ungueltig
PopupStrip.setItemLabelAndCut( mi, label );
h.put( menuItem, mi ); // mit neuem wieder anmelden
}
return( mi != null );
}
/**
* JMenuItem aus ActionCommand bzw. JLabel ermitteln
*
* @param menuItem ActionString des gewuenschten Items
* @return null, wenn Item nicht gefunden wurde
*/
public JMenuItem getItem( String menuItem )
{
return( (JMenuItem) h.get( menuItem ));
}
public boolean addItem( String subMenu, String menuItem )
{
JMenu sm;
Object o;
JMenuItem mi = new JMenuItem();
PopupStrip.setItemLabelAndCut( mi, menuItem );
if( subMenu != null ) {
o = getItem( subMenu );
if( o == null || !(o instanceof JMenu) ) return false;
sm = (JMenu) o;
sm.add( mi );
} else {
this.add( mi );
}
mi.addActionListener( listener );
h.put( menuItem, mi );
return true;
}
public boolean removeItem( String menuItem )
{
JMenuItem mi = getItem( menuItem );
if( mi != null ) {
h.remove( menuItem );
mi.removeActionListener( listener );
mi.getParent().remove( mi );
}
return( mi != null );
}
// -------- quasi-protected methods --------
/**
* Strip erstellen
* ONLY TO BE CALLED BY THIS CLASS OR POPUPSTRIP !!!
*
* @param m aufrufender MenuStrip oder PopupStrip
* @param h Hashtable mit Items als Objekte und ActionCommand als Keys
* @param menuItems inneres Array: 1 String fuer normale Items, mehrere fuer SubMenus
* ( "&c"-Anfang fuer Shortcuts; "#"-Ende fuer JCheckBoxes )
* @param listener ActionListener, der die Menuwahlen verarbeiten soll
*/
public static void createStrip( JPopupMenu m, Hashtable<String, JMenuItem> h, String[][] menuItems, ActionListener listener )
{
Object m2;
JMenuItem mi;
boolean sub;
String miStr;
for( int i = 0; i < menuItems.length; i++ ) {
sub = (menuItems[ i ].length > 1);
m2 = m;
for( int j = 0; j < menuItems[ i ].length; j++ ) {
miStr = menuItems[ i ][ j ];
if( miStr == null ) {
if( m2 instanceof JPopupMenu ) {
((JPopupMenu) m2).addSeparator();
} else if( m2 instanceof JMenu ) {
((JMenu) m2).addSeparator();
}
} else {
if( (j == 0) && (sub) ) {
m2 = new JMenu();
mi = (JMenu) m2;
m.add( mi );
} else {
if( miStr.endsWith( "#" )) { // JCheckBox
mi = new JCheckBoxMenuItem();
} else {
mi = new JMenuItem();
}
if( m2 instanceof JPopupMenu ) {
((JPopupMenu) m2).add( mi );
} else if( m2 instanceof JMenu ) {
((JMenu) m2).add( mi );
}
}
setItemLabelAndCut( mi, miStr );
mi.addActionListener( listener );
h.put( miStr, mi ); // Item in die Hashtable aufnehmen; Key = ActionCommand
}
}
}
}
/**
* Sichtbares JLabel und Shortcut des JMenuItems setzen
* ONLY TO BE CALLED BY THIS CLASS AND POPUPSTRIP !!!
*
* @param mi JMenuItem
* @param label String ggf. inklusive Shortcut
*/
public static void setItemLabelAndCut( JMenuItem mi, String label )
{
mi.setActionCommand( label );
if( label.endsWith( "#" )) { // JCheckBox
label = label.substring( 0, label.length() - 1 );
}
if( label.startsWith( "&" )) {
// mi.setShortcut( new MenuShortcut( label.charAt( 1 )));
label = label.substring( 2 );
} else {
// mi.deleteShortcut();
}
mi.setText( label );
}
}