001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Alexander T. Simbirtsev
019: * @version $Revision$
020: */package javax.swing.plaf.basic;
021:
022: import java.awt.Component;
023: import java.awt.Dimension;
024: import java.awt.event.ActionEvent;
025: import java.awt.event.MouseEvent;
026: import java.beans.PropertyChangeEvent;
027: import java.beans.PropertyChangeListener;
028:
029: import javax.swing.AbstractAction;
030: import javax.swing.ActionMap;
031: import javax.swing.JComponent;
032: import javax.swing.JMenu;
033: import javax.swing.JMenuBar;
034: import javax.swing.LookAndFeel;
035: import javax.swing.MenuElement;
036: import javax.swing.MenuSelectionManager;
037: import javax.swing.SwingUtilities;
038: import javax.swing.Timer;
039: import javax.swing.UIManager;
040: import javax.swing.event.ChangeEvent;
041: import javax.swing.event.ChangeListener;
042: import javax.swing.event.MenuEvent;
043: import javax.swing.event.MenuListener;
044: import javax.swing.event.MouseInputListener;
045: import javax.swing.plaf.ActionMapUIResource;
046: import javax.swing.plaf.ComponentUI;
047:
048: import org.apache.harmony.x.swing.StringConstants;
049: import org.apache.harmony.x.swing.Utilities;
050:
051: public class BasicMenuUI extends BasicMenuItemUI {
052:
053: // this class is obsolete
054: public class ChangeHandler implements ChangeListener {
055: public boolean isSelected;
056: public JMenu menu;
057: public BasicMenuUI ui;
058: public Component wasFocused;
059:
060: public ChangeHandler(final JMenu menu, final BasicMenuUI ui) {
061: this .menu = menu;
062: this .ui = ui;
063: }
064:
065: public void stateChanged(final ChangeEvent e) {
066: }
067: }
068:
069: protected class MouseInputHandler implements MouseInputListener {
070: public void mouseEntered(final MouseEvent e) {
071: final MenuSelectionManager manager = MenuSelectionManager
072: .defaultManager();
073: if (!manager.isComponentPartOfCurrentMenu(menuItem)) {
074: return;
075: }
076: if (Utilities.isEmptyArray(manager.getSelectedPath())) {
077: return;
078: }
079: if (!menuItem.isEnabled()) {
080: return;
081: }
082: if (openMenuTimer != null) {
083: openMenuTimer.stop();
084: }
085: final JMenu menu = (JMenu) menuItem;
086: MenuElement[] path = Utilities.addToPath(manager
087: .getSelectedPath(), menu);
088: if (menu.isTopLevelMenu()) {
089: path = Utilities.addToPath(path, menu.getPopupMenu());
090: manager.setSelectedPath(path);
091: OPEN_POPUP_ACTION.openPopup(menu);
092: } else {
093: manager.setSelectedPath(path);
094: setupPostTimer(menu);
095: }
096: }
097:
098: public void mousePressed(final MouseEvent e) {
099: final JMenu menu = (JMenu) menuItem;
100: MenuSelectionManager defaultManager = MenuSelectionManager
101: .defaultManager();
102: if (menu.isTopLevelMenu()) {
103: if (Utilities.isEmptyArray(defaultManager
104: .getSelectedPath())) {
105: defaultManager.setSelectedPath(new MenuElement[] {
106: (JMenuBar) menu.getParent(), menu });
107: OPEN_POPUP_ACTION.openPopup(menu);
108: } else {
109: defaultManager.clearSelectedPath();
110: }
111: }
112: }
113:
114: public void mouseReleased(final MouseEvent e) {
115: MenuSelectionManager defaultManager = MenuSelectionManager
116: .defaultManager();
117: if (defaultManager.componentForPoint(e.getComponent(), e
118: .getPoint()) == null) {
119: defaultManager.clearSelectedPath();
120: } else {
121: defaultManager.processMouseEvent(e);
122: }
123: }
124:
125: public void mouseClicked(final MouseEvent e) {
126: MenuSelectionManager.defaultManager().processMouseEvent(e);
127: }
128:
129: public void mouseDragged(final MouseEvent e) {
130: MenuSelectionManager.defaultManager().processMouseEvent(e);
131: }
132:
133: public void mouseMoved(final MouseEvent e) {
134: MenuSelectionManager.defaultManager().processMouseEvent(e);
135: }
136:
137: public void mouseExited(final MouseEvent e) {
138: MenuSelectionManager.defaultManager().processMouseEvent(e);
139: }
140: }
141:
142: private class MenuHandler implements MenuListener,
143: PropertyChangeListener {
144: public void menuCanceled(final MenuEvent e) {
145: }
146:
147: public void menuDeselected(final MenuEvent e) {
148: menuItem.repaint();
149: }
150:
151: public void menuSelected(final MenuEvent e) {
152: menuItem.repaint();
153: }
154:
155: public void propertyChange(final PropertyChangeEvent event) {
156: menuItem.revalidate();
157: menuItem.repaint();
158: }
159: }
160:
161: private static class OpenPopupAction extends AbstractAction {
162: private JMenu menu;
163:
164: public void setMenu(final JMenu menu) {
165: this .menu = menu;
166: }
167:
168: public JMenu getMenu() {
169: return menu;
170: }
171:
172: public void openPopup(final JMenu menu) {
173: setMenu(menu);
174: doOpenPopup();
175: }
176:
177: public void actionPerformed(final ActionEvent e) {
178: doOpenPopup();
179: }
180:
181: private void doOpenPopup() {
182: menu.setPopupMenuVisible(true);
183: }
184: }
185:
186: private static class MnemonicAction extends AbstractAction {
187: public void actionPerformed(final ActionEvent e) {
188: final JMenu menu = (JMenu) e.getSource();
189: final MenuElement menuItem = getFirstMenuItem(menu);
190: final MenuElement newSelection = (menuItem != null) ? menuItem
191: : menu.getPopupMenu();
192: final MenuElement[] path = Utilities
193: .getMenuElementPath(newSelection);
194: MenuSelectionManager.defaultManager().setSelectedPath(path);
195: }
196:
197: private MenuElement getFirstMenuItem(final JMenu menu) {
198: final int numElements = menu.getMenuComponentCount();
199: for (int i = 0; i < numElements; i++) {
200: final Component menuComponent = menu
201: .getMenuComponent(i);
202: if (menuComponent.isEnabled()
203: && menuComponent instanceof MenuElement) {
204: return (MenuElement) menuComponent;
205: }
206: }
207: return null;
208: }
209: }
210:
211: private final static OpenPopupAction OPEN_POPUP_ACTION = new OpenPopupAction();
212: private final static MnemonicAction MNEMONIC_ACTION = new MnemonicAction();
213:
214: protected ChangeListener changeListener;
215: protected MenuListener menuListener;
216: protected PropertyChangeListener propertyChangeListener;
217:
218: private MenuHandler menuHandler;
219:
220: private static final String PROPERTY_PREFIX = "Menu";
221:
222: public static ComponentUI createUI(final JComponent c) {
223: return new BasicMenuUI();
224: }
225:
226: protected ChangeListener createChangeListener(final JComponent c) {
227: return null;
228: }
229:
230: protected MenuListener createMenuListener(final JComponent c) {
231: return menuHandler;
232: }
233:
234: protected PropertyChangeListener createPropertyChangeListener(
235: final JComponent c) {
236: return (menuHandler == null) ? new MenuHandler() : menuHandler;
237: }
238:
239: protected MouseInputListener createMouseInputListener(
240: final JComponent c) {
241: return new MouseInputHandler();
242: }
243:
244: protected void setupPostTimer(final JMenu menu) {
245: if (!menu.isSelected()) {
246: return;
247: }
248:
249: if (openMenuTimer == null) {
250: openMenuTimer = new Timer(menu.getDelay(),
251: OPEN_POPUP_ACTION);
252: openMenuTimer.setRepeats(false);
253: } else {
254: openMenuTimer.stop();
255: openMenuTimer.setInitialDelay(menu.getDelay());
256: }
257: OPEN_POPUP_ACTION.setMenu(menu);
258: openMenuTimer.start();
259: }
260:
261: public Dimension getMaximumSize(final JComponent c) {
262: if (!((JMenu) menuItem).isTopLevelMenu()) {
263: return super .getMaximumSize(c);
264: }
265: Dimension result = c.getPreferredSize();
266: result.height = Short.MAX_VALUE;
267: return result;
268: }
269:
270: protected String getPropertyPrefix() {
271: return PROPERTY_PREFIX;
272: }
273:
274: protected void installDefaults() {
275: super .installDefaults();
276: LookAndFeel.installProperty(menuItem, "opaque", Boolean.FALSE);
277: }
278:
279: protected void installKeyboardActions() {
280: ActionMap actionMap = new ActionMapUIResource();
281: actionMap.put(StringConstants.MNEMONIC_ACTION, MNEMONIC_ACTION);
282: actionMap.setParent(((BasicLookAndFeel) UIManager
283: .getLookAndFeel()).getAudioActionMap());
284: SwingUtilities.replaceUIActionMap(menuItem, actionMap);
285: }
286:
287: protected void uninstallKeyboardActions() {
288: SwingUtilities.replaceUIActionMap(menuItem, null);
289: }
290:
291: protected void installListeners() {
292: if (menuItem == null) {
293: return;
294: }
295:
296: final JMenu menu = (JMenu) menuItem;
297: menuDragMouseListener = createMenuDragMouseListener(menu);
298: menu.addMenuDragMouseListener(menuDragMouseListener);
299: mouseInputListener = createMouseInputListener(menu);
300: menu.addMouseListener(mouseInputListener);
301: menu.addMouseMotionListener(mouseInputListener);
302: menuKeyListener = createMenuKeyListener(menu);
303: menu.addMenuKeyListener(menuKeyListener);
304: propertyChangeListener = createPropertyChangeListener(menuItem);
305: menu.addPropertyChangeListener(propertyChangeListener);
306: changeListener = createChangeListener(menuItem);
307: menu.addChangeListener(changeListener);
308: menuListener = createMenuListener(menu);
309: menu.addMenuListener(menuListener);
310: }
311:
312: protected void uninstallListeners() {
313: if (menuItem == null) {
314: return;
315: }
316:
317: final JMenu menu = (JMenu) menuItem;
318: menu.removeMenuDragMouseListener(menuDragMouseListener);
319: menuDragMouseListener = null;
320: menu.removeMouseListener(mouseInputListener);
321: menu.removeMouseMotionListener(mouseInputListener);
322: mouseInputListener = null;
323: menu.removeMenuKeyListener(menuKeyListener);
324: menuKeyListener = null;
325: menu.removePropertyChangeListener(propertyChangeListener);
326: propertyChangeListener = null;
327: menu.removeChangeListener(changeListener);
328: changeListener = null;
329: menu.removeMenuListener(menuListener);
330: menuListener = null;
331: }
332:
333: boolean isArrowToBeDrawn() {
334: return (menuItem != null) ? super .isArrowToBeDrawn()
335: && !((JMenu) menuItem).isTopLevelMenu() : false;
336: }
337:
338: boolean isPaintArmed() {
339: return menuItem.isArmed() || menuItem.isSelected();
340: }
341: }
|