📄 abstractopenmapmenu.java
字号:
// **********************************************************************// // <copyright>// // BBN Technologies// 10 Moulton Street// Cambridge, MA 02138// (617) 873-8000// // Copyright (C) BBNT Solutions LLC. All rights reserved.// // </copyright>// **********************************************************************// // $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/gui/AbstractOpenMapMenu.java,v $// $RCSfile: AbstractOpenMapMenu.java,v $// $Revision: 1.6.2.3 $// $Date: 2005/02/11 22:51:23 $// $Author: dietrick $// // **********************************************************************package com.bbn.openmap.gui;import java.awt.Component;import java.beans.PropertyVetoException;import java.beans.VetoableChangeListener;import java.beans.beancontext.BeanContext;import java.beans.beancontext.BeanContextChild;import java.beans.beancontext.BeanContextChildSupport;import java.beans.beancontext.BeanContextMembershipEvent;import java.beans.beancontext.BeanContextMembershipListener;import java.util.Hashtable;import java.util.Iterator;import java.util.Properties;import java.util.Vector;import javax.swing.JMenu;import javax.swing.JMenuItem;import javax.swing.JSeparator;import com.bbn.openmap.Environment;import com.bbn.openmap.I18n;import com.bbn.openmap.Layer;import com.bbn.openmap.LightMapHandlerChild;import com.bbn.openmap.MapHandler;import com.bbn.openmap.PropertyConsumer;import com.bbn.openmap.util.ComponentFactory;import com.bbn.openmap.util.Debug;import com.bbn.openmap.util.PropUtils;/** * Abstract Menu Object that takes care of common bean context-related * functionality. Components on this Menu that implement the * LightMapHandlerChild interface, that also are created via the * constructor, or created when the properties are evaluated, will be * given the MapHandler through the findAndInit(Object) method. These * components will also receive findAndInit() and findAndUndo() calls * when other components are added to the MapHandler (BeanContext). * This makes the LightMapHandlerChild menu components invisible to * MapHandler components, but able to connect to them. * <P> * * If you have a component that needs to be added to the menu that * should in the MapHandler, you should *NOT* make it a * LightMapHandlerChild, but implement the same methods as the * MapHandlerChild and add it to the MapHandler before adding it to * this menu. If the component is a LightMapHandlerChild, added to * this menu, and also added to the MapHandler, it will receive double * membership notifications which may be confusing. * <P> * * AbstractOpenMapMenus can be configure via properties. You can set, * with 'menu' as a property prefix: * <P> * * <pre> * * * * # Title used in the Menu Bar. * menu.prettyName=Menu Title * # The letter to use as Mnemonic * menu.mnemonic=M * # A marker name list of items to use in the menu. 'sep' inserts a * # separator, property classname definition not needed. * menu.items=first second sep third * first.class=Classname of first menu item * # You can add properties for Menu Item, if it is a PropertyConsumer. * #first.property1=prop1 * second.class=classname * third.class=classname * * * * </pre> * * If no properties are set, the name, mnemonic and any items added in * the constructor will be in the menu. Any items in the properties * will be added to items created and added in the constructor - this * really applies to any subclasses to this class. */abstract public class AbstractOpenMapMenu extends JMenu implements BeanContextChild, BeanContextMembershipListener, PropertyConsumer, MenuBarMenu, LightMapHandlerChild { /** * All AbstractOpenMapMenus have access to an I18n object, which * is provided by the Environment. */ protected I18n i18n = Environment.getI18n(); protected BeanContextChildSupport beanContextChildSupport = new BeanContextChildSupport(this); /** * Token uniquely identifying this component in the application * properties. */ protected String propertyPrefix = null; /** * A hashtable to keep track of item prefixes and their * components, for restructuring properties later. Only created if * menu uses properties to create items. */ protected Hashtable items = null; public final static String ItemsProperty = "items"; public final static String SeparatorProperty = "sep"; public final static String PrettyNameProperty = Layer.PrettyNameProperty; public final static String MnemonicProperty = "mnemonic"; protected String itemsPropertyContents = null; protected Hashtable itemsProperties = null; public AbstractOpenMapMenu() { super(); } public AbstractOpenMapMenu(String title) { super(title); } /** Method for BeanContextChild interface. */ public BeanContext getBeanContext() { return beanContextChildSupport.getBeanContext(); } /** Method for BeanContextChild interface. */ public void setBeanContext(BeanContext in_bc) throws PropertyVetoException { beanContextChildSupport.setBeanContext(in_bc); if (in_bc == null) { return; } in_bc.addBeanContextMembershipListener(this); // let MenuItems find it if they want to look for // it there, or if they want to add themselves. Not sure what // the ConcurrentModificationException ramifications will be, // though. findAndInit((Object) in_bc); findAndInit(in_bc.iterator()); } /** Method for BeanContextMembership interface. */ public void childrenAdded(BeanContextMembershipEvent bcme) { findAndInit(bcme.iterator()); } /** Method for BeanContextMembership interface. */ public void childrenRemoved(BeanContextMembershipEvent bcme) { findAndUndo(bcme.iterator()); } /** * Subclasses should no longer implement this method. Use the * findAndUndo(Object) instead, so subclasses and superclasses can * be given the opportunity to use the object, too. */ public void findAndUnInit(Iterator it) { while (it.hasNext()) { findAndUndo(it.next()); } } /** * Method called when an object is removed from the MapHandler. * Called to let menu objects disconnect from it. */ public void findAndUndo(Object someObj) { Component menuItems[] = getMenuComponents(); for (int i = 0; i < menuItems.length; i++) { Component item = menuItems[i]; if (item instanceof LightMapHandlerChild) { ((LightMapHandlerChild) item).findAndUndo(someObj); } } } /** * Subclasses should no longer implement this method. Use the * findAndInit(Object) instead, so subclasses and superclasses can * be given the opportunity to use the object, too. */ public void findAndInit(Iterator it) { while (it.hasNext()) { findAndInit(it.next()); } } /** * Method called when an object is added from the MapHandler. * Called to let menu objects connect to it. */ public void findAndInit(Object someObj) { Component menuItems[] = getMenuComponents(); for (int i = 0; i < menuItems.length; i++) { Component item = menuItems[i]; if (item instanceof LightMapHandlerChild) { ((LightMapHandlerChild) item).findAndInit(someObj); } } } /** Method for BeanContextChild interface. */ public void addVetoableChangeListener(String propertyName, VetoableChangeListener in_vcl) { beanContextChildSupport.addVetoableChangeListener(propertyName, in_vcl); } /** Method for BeanContextChild interface. */ public void removeVetoableChangeListener(String propertyName, VetoableChangeListener in_vcl) { beanContextChildSupport.removeVetoableChangeListener(propertyName, in_vcl); } /** * Return the MapHandler, if it's been set. May be null if the * Menu hasn't been added to the MapHandler. */ public MapHandler getMapHandler() { return (MapHandler) beanContextChildSupport.getBeanContext(); } /** * Sets the properties for the OMComponent. * * @param props the <code>Properties</code> object. */ public void setProperties(java.util.Properties props) { setProperties(getPropertyPrefix(), props); } /** * Sets the properties for the OMComponent. * * @param prefix the token to prefix the property names * @param props the <code>Properties</code> object */ public void setProperties(String prefix, java.util.Properties props) { setPropertyPrefix(prefix); String realPrefix = PropUtils.getScopedPropertyPrefix(prefix); String prettyName = props.getProperty(realPrefix + PrettyNameProperty); if (prettyName != null) { setText(prettyName); } String mnemonicString = props.getProperty(realPrefix + MnemonicProperty); if (mnemonicString != null) { setMnemonic((int) mnemonicString.charAt(0)); } itemsPropertyContents = props.getProperty(realPrefix + ItemsProperty); Vector menuItems = PropUtils.parseSpacedMarkers(itemsPropertyContents); if (!menuItems.isEmpty()) { int nMenuItems = menuItems.size(); if (Debug.debugging("menu")) { Debug.output("Menu " + getText() + " created with " + nMenuItems + " item" + (nMenuItems == 1 ? "" : "s") + " in properties"); } for (int i = 0; i < nMenuItems; i++) { String itemPrefix = (String) menuItems.elementAt(i); if (itemPrefix.equals(SeparatorProperty)) { add(new JSeparator()); continue; } String classProperty = itemPrefix + ".class"; String className = props.getProperty(classProperty); if (className == null) { Debug.error("Menu " + getText() + ".setProperties(): Failed to locate property \"" + classProperty + "\"\n Skipping menu item \"" + itemPrefix + "\""); continue; } if (itemsProperties == null) { itemsProperties = new Properties(); } itemsProperties.put(classProperty, className); Object obj = ComponentFactory.create(className, itemPrefix, props); if (obj instanceof Component) { add((Component) obj); } else if (obj instanceof JMenuItem) { add((JMenuItem) obj); } } } else { if (Debug.debugging("menu")) { Debug.output("Menu " + getText() + " created without items in properties"); } } } /** * PropertyConsumer method, to fill in a Properties object, * reflecting the current values of the OMComponent. If the * component has a propertyPrefix set, the property keys should * have that prefix plus a separating '.' prepended to each * propery key it uses for configuration. * * @param props a Properties object to load the PropertyConsumer * properties into. If props equals null, then a new * Properties object should be created. * @return Properties object containing PropertyConsumer property * values. If getList was not null, this should equal * getList. Otherwise, it should be the Properties object * created by the PropertyConsumer. */ public Properties getProperties(Properties props) { if (props == null) { props = new Properties(); } String prefix = PropUtils.getScopedPropertyPrefix(propertyPrefix); props.put(prefix + PrettyNameProperty, getText()); props.put(prefix + MnemonicProperty, "" + ((char) getMnemonic())); if (itemsPropertyContents != null) { props.put(prefix + ItemsProperty, itemsPropertyContents); } if (itemsProperties != null) { props.putAll(itemsProperties); } return props; } /** * Method to fill in a Properties object with values reflecting * the properties able to be set on this PropertyConsumer. The key * for each property should be the raw property name (without a * prefix) with a value that is a String that describes what the * property key represents, along with any other information about * the property that would be helpful (range, default value, * etc.). For Layer, this method should at least return the * 'prettyName' property. * * @param list a Properties object to load the PropertyConsumer * properties into. If getList equals null, then a new * Properties object should be created. * @return Properties object containing PropertyConsumer property * values. If getList was not null, this should equal * getList. Otherwise, it should be the Properties object * created by the PropertyConsumer. */ public Properties getPropertyInfo(Properties list) { if (list == null) { list = new Properties(); } return list; } /** * Set the property key prefix that should be used by the * PropertyConsumer. The prefix, along with a '.', should be * prepended to the property keys known by the PropertyConsumer. * * @param prefix the prefix String. */ public void setPropertyPrefix(String prefix) { propertyPrefix = prefix; } /** * Get the property key prefix that is being used to prepend to * the property keys for Properties lookups. * * @return the property prefix for the menu */ public String getPropertyPrefix() { return propertyPrefix; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -