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.KeyboardFocusManager;
024: import java.awt.Window;
025: import java.awt.event.ActionEvent;
026: import java.awt.event.ComponentEvent;
027: import java.awt.event.ComponentListener;
028: import java.awt.event.ContainerEvent;
029: import java.awt.event.ContainerListener;
030: import java.awt.event.WindowEvent;
031: import java.awt.event.WindowListener;
032: import java.util.ArrayList;
033:
034: import javax.swing.AbstractAction;
035: import javax.swing.ActionMap;
036: import javax.swing.BoxLayout;
037: import javax.swing.DefaultFocusManager;
038: import javax.swing.JComponent;
039: import javax.swing.JMenuBar;
040: import javax.swing.JRootPane;
041: import javax.swing.LookAndFeel;
042: import javax.swing.MenuSelectionManager;
043: import javax.swing.SwingUtilities;
044: import javax.swing.UIManager;
045: import javax.swing.event.AncestorEvent;
046: import javax.swing.event.AncestorListener;
047: import javax.swing.event.ChangeEvent;
048: import javax.swing.event.ChangeListener;
049: import javax.swing.plaf.ActionMapUIResource;
050: import javax.swing.plaf.ComponentUI;
051: import javax.swing.plaf.MenuBarUI;
052:
053: import org.apache.harmony.x.swing.Utilities;
054:
055: public class BasicMenuBarUI extends MenuBarUI {
056:
057: private static class FocusAction extends AbstractAction implements
058: WindowListener, ComponentListener {
059: public static final String KEY = "takeFocus";
060:
061: private final ArrayList menuBars = new ArrayList();
062:
063: public void addMenuBar(final JMenuBar menuBar) {
064: if (menuBars.contains(menuBar)) {
065: menuBars.remove(menuBar);
066: }
067: menuBars.add(menuBar);
068:
069: Window w = SwingUtilities.getWindowAncestor(menuBar);
070: if (w != null) {
071: w.addWindowListener(this );
072: w.addComponentListener(this );
073: }
074: }
075:
076: public void removeMenuBar(final JMenuBar menuBar) {
077: menuBars.remove(menuBar);
078:
079: Window w = SwingUtilities.getWindowAncestor(menuBar);
080: if (w != null) {
081: w.removeWindowListener(this );
082: w.addComponentListener(this );
083: }
084: }
085:
086: public void actionPerformed(final ActionEvent e) {
087: Component c = KeyboardFocusManager
088: .getCurrentKeyboardFocusManager().getFocusOwner();
089: JMenuBar menuBar = null;
090: final JRootPane rootPane = SwingUtilities.getRootPane(c);
091: if (rootPane != null) {
092: menuBar = rootPane.getJMenuBar();
093: }
094: if (menuBar == null) {
095: menuBar = getActiveMenuBar();
096: }
097: if (menuBar == null || menuBar.getMenuCount() == 0) {
098: return;
099: }
100: menuBar.getMenu(0).doClick(0);
101: }
102:
103: private JMenuBar getActiveMenuBar() {
104: for (int i = menuBars.size() - 1; i >= 0; i--) {
105: final JMenuBar menuBar = (JMenuBar) menuBars.get(i);
106: if (menuBar.isShowing()) {
107: return menuBar;
108: }
109: }
110: return null;
111: }
112:
113: public void windowClosed(final WindowEvent e) {
114: MenuSelectionManager.defaultManager().clearSelectedPath();
115: }
116:
117: public void componentMoved(final ComponentEvent e) {
118: MenuSelectionManager.defaultManager().clearSelectedPath();
119: }
120:
121: public void componentResized(final ComponentEvent e) {
122: MenuSelectionManager.defaultManager().clearSelectedPath();
123: }
124:
125: public void windowIconified(final WindowEvent e) {
126: MenuSelectionManager.defaultManager().clearSelectedPath();
127: }
128:
129: public void windowDeactivated(final WindowEvent e) {
130: }
131:
132: public void windowDeiconified(final WindowEvent e) {
133: }
134:
135: public void windowOpened(final WindowEvent e) {
136: }
137:
138: public void windowActivated(final WindowEvent e) {
139: }
140:
141: public void windowClosing(final WindowEvent e) {
142: }
143:
144: public void componentHidden(final ComponentEvent e) {
145: }
146:
147: public void componentShown(final ComponentEvent e) {
148: }
149: }
150:
151: private class ChangeContainerHandler implements ChangeListener,
152: ContainerListener, AncestorListener {
153: public void ancestorAdded(final AncestorEvent e) {
154: FOCUS_ACTION.addMenuBar((JMenuBar) e.getComponent());
155: MenuKeyBindingProcessor.attach();
156: }
157:
158: public void ancestorRemoved(final AncestorEvent e) {
159: MenuKeyBindingProcessor.detach();
160: FOCUS_ACTION.removeMenuBar((JMenuBar) e.getComponent());
161: }
162:
163: public void stateChanged(final ChangeEvent e) {
164: }
165:
166: public void componentAdded(final ContainerEvent e) {
167: }
168:
169: public void componentRemoved(final ContainerEvent e) {
170: }
171:
172: public void ancestorMoved(final AncestorEvent e) {
173: }
174: }
175:
176: private static final String PROPERTY_PREFIX = "MenuBar.";
177:
178: private static final FocusAction FOCUS_ACTION = new FocusAction();
179:
180: protected ChangeListener changeListener;
181: protected ContainerListener containerListener;
182: protected JMenuBar menuBar;
183:
184: private ChangeContainerHandler handler;
185: private MenuKeyBindingProcessor menuKeyBindingProcessor;
186:
187: static {
188: DefaultFocusManager.getCurrentKeyboardFocusManager()
189: .addKeyEventPostProcessor(new AcceleratorsProcessor());
190: }
191:
192: public static ComponentUI createUI(final JComponent c) {
193: return new BasicMenuBarUI();
194: }
195:
196: public void installUI(final JComponent c) {
197: menuBar = (JMenuBar) c;
198: if (Utilities.isUIResource(menuBar.getLayout())) {
199: menuBar.setLayout(new DefaultMenuLayout(menuBar,
200: BoxLayout.X_AXIS));
201: }
202: installDefaults();
203: installKeyboardActions();
204: installListeners();
205: }
206:
207: public void uninstallUI(final JComponent c) {
208: uninstallListeners();
209: uninstallKeyboardActions();
210: uninstallDefaults();
211: menuBar = null;
212: }
213:
214: protected ChangeListener createChangeListener() {
215: return (handler != null) ? handler
216: : (handler = new ChangeContainerHandler());
217: }
218:
219: protected ContainerListener createContainerListener() {
220: return (handler != null) ? handler
221: : (handler = new ChangeContainerHandler());
222: }
223:
224: protected void installDefaults() {
225: LookAndFeel.installColorsAndFont(menuBar, PROPERTY_PREFIX
226: + "background", PROPERTY_PREFIX + "foreground",
227: PROPERTY_PREFIX + "font");
228: LookAndFeel.installBorder(menuBar, PROPERTY_PREFIX + "border");
229: LookAndFeel.installProperty(menuBar, "opaque", Boolean.TRUE);
230: }
231:
232: protected void uninstallDefaults() {
233: LookAndFeel.uninstallBorder(menuBar);
234: }
235:
236: protected void installKeyboardActions() {
237: ActionMap actionMap = new ActionMapUIResource();
238: actionMap.put(FocusAction.KEY, FOCUS_ACTION);
239: SwingUtilities.replaceUIActionMap(menuBar, actionMap);
240:
241: SwingUtilities.replaceUIInputMap(menuBar,
242: JComponent.WHEN_IN_FOCUSED_WINDOW, LookAndFeel
243: .makeComponentInputMap(menuBar,
244: (Object[]) UIManager
245: .get(PROPERTY_PREFIX
246: + "windowBindings")));
247: }
248:
249: protected void uninstallKeyboardActions() {
250: SwingUtilities.replaceUIInputMap(menuBar,
251: JComponent.WHEN_IN_FOCUSED_WINDOW, null);
252: SwingUtilities.replaceUIActionMap(menuBar, null);
253: }
254:
255: protected void installListeners() {
256: changeListener = createChangeListener();
257: containerListener = createContainerListener();
258: menuBar.addContainerListener(containerListener);
259: menuBar.addAncestorListener(handler);
260: }
261:
262: protected void uninstallListeners() {
263: menuBar.removeAncestorListener(handler);
264: menuBar.removeContainerListener(containerListener);
265: changeListener = null;
266: containerListener = null;
267: }
268:
269: }
|