package com.limegroup.gnutella.gui.menu;
import java.awt.Font;
import java.awt.event.ActionListener;
import java.lang.reflect.Field;
import java.util.Locale;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JRadioButtonMenuItem;
import com.limegroup.gnutella.gui.GUIMediator;
import com.limegroup.gnutella.util.CommonUtils;
/**
* Provides a skeletal implementation of the <tt>Menu</tt> interface to
* minimize the necessary work in classes that extend <tt>AbstractMenu</tt>.
*/
//2345678|012345678|012345678|012345678|012345678|012345678|012345678|012345678|
abstract class AbstractMenu implements Menu {
/**
* The font menus should use.
*/
static final Font FONT = new Font("Dialog", Font.PLAIN, 11);
/**
* Constant handle to the <tt>JMenu</tt> instance for this
* <tt>AbstractMenu</tt>.
*/
protected final JMenu MENU = new JMenu();
/**
* Cache the <tt>KeyEvent</tt> class to avoid looking it up every time.
*/
private static Class _keyEventClass = null;
/**
* Creates a new <tt>AbstractMenu</tt>, using the <tt>key</tt>
* argument for setting the locale-specific title and
* accessibility text.
*
* @param key the key for locale-specific string resources unique
* to the menu
*/
protected AbstractMenu(final String key) {
String titleKey = "MENU_" + key + "_TITLE";
String titleMnemonicKey = titleKey + "_MNEMONIC";
MENU.setText(GUIMediator.getStringResource(titleKey));
if(_keyEventClass == null) {
try {
_keyEventClass =
Class.forName("java.awt.event.KeyEvent");
} catch(ClassNotFoundException e) {
e.printStackTrace();
}
}
MENU.setMnemonic(getCodeForCharKey(titleMnemonicKey));
MENU.setFont(FONT);
}
/**
* Returns the <tt>JMenu</tt> instance for this <tt>AbstractMenu</tt>.
*
* @return the <tt>JMenu</tt> instance for this <tt>AbstractMenu</tt>
*/
public JMenu getMenu() {
return MENU;
}
/**
* Adds a menu item to this menu, using the <tt>key</tt> argument
* to obtain locale-specific resources.
*
* @param key the key to use for obtaining locale-specific resources
* @param listener the <tt>ActionListener</tt> to add to this menu
* item
*/
protected JMenuItem addMenuItem(final String key,
final ActionListener listener) {
String labelKey = "MENU_" + key;
String accessKey = labelKey + "_ACCESSIBLE";
String mnemonicKey = labelKey + "_MNEMONIC";
String label = GUIMediator.getStringResource(labelKey);
String access = GUIMediator.getStringResource(accessKey);
int mnemonic = getCodeForCharKey(mnemonicKey);
JMenuItem menuItem = new JMenuItem(label, mnemonic);
menuItem.getAccessibleContext().setAccessibleDescription(access);
menuItem.addActionListener(listener);
menuItem.setFont(FONT);
MENU.add(menuItem);
return menuItem;
}
/**
* Adds a menu item to this menu. If the current platform is OSX,
* the menu will be of the type JRadioButtonMenuItem, otherwise
* it will be of the type JCheckboxMenuItem.
* This method is used to get around the JCheckBoxMenuItem bug when
* using the Mac screen menu bar.
*
* @param key the key to use for obtaining locale-specific resources
* @param listener the <tt>ActionListener</tt> to add to this menu
* item
* @param enabled whether or not the toggle is enabled by default
*/
protected JMenuItem addToggleMenuItem(final String key,
final ActionListener listener,
boolean enabled) {
String labelKey = "MENU_" + key;
String accessKey = "MENU_" + key + "_ACCESSIBLE";
String mnemonicKey = "MENU_" + key + "_MNEMONIC";
String label = GUIMediator.getStringResource(labelKey);
String access = GUIMediator.getStringResource(accessKey);
int mnemonic = getCodeForCharKey(mnemonicKey);
JMenuItem menuItem;
if( CommonUtils.isMacOSX() )
menuItem = new JRadioButtonMenuItem(label, enabled);
else
menuItem = new JCheckBoxMenuItem(label, enabled);
menuItem.setMnemonic(mnemonic);
menuItem.getAccessibleContext().setAccessibleDescription(access);
menuItem.addActionListener(listener);
menuItem.setFont(FONT);
MENU.add(menuItem);
return menuItem;
}
/**
* Adds a separator to the <tt>JMenu</tt> instance.
*/
protected void addSeparator() {
MENU.addSeparator();
}
/**
* Using a little reflection here for a lack of any better way
* to access locale-specific char codes for menu mnemonics.
* We could at least defer this in the future.
*
* @param str the key for the locale-specific char resource to
* look up -- the key as it appears in the locale-specific
* properties file
* @return the code for the passed-in key as defined in
* <tt>java.awt.event.KeyEvent</tt>, or -1 if no key code
* could be found
*/
protected int getCodeForCharKey(String str) {
int charCode = -1;
String charStr =
GUIMediator.getStringResource(str).toUpperCase(Locale.US);
if(charStr.length()>1) return -1;
try {
Field charField = _keyEventClass.getField("VK_"+charStr);
charCode = charField.getInt(_keyEventClass);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return charCode;
}
}