1. /*
  2. * @(#)BasicMenuBarUI.java 1.78 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing.plaf.basic;
  8. import javax.swing.*;
  9. import javax.swing.event.*;
  10. import java.awt.Color;
  11. import java.awt.Component;
  12. import java.awt.Container;
  13. import java.awt.Dimension;
  14. import java.awt.Graphics;
  15. import java.awt.Insets;
  16. import java.awt.Point;
  17. import java.awt.Rectangle;
  18. import java.awt.event.*;
  19. import java.beans.PropertyChangeEvent;
  20. import java.beans.PropertyChangeListener;
  21. import javax.swing.border.*;
  22. import javax.swing.plaf.*;
  23. /**
  24. * A default L&F implementation of MenuBarUI. This implementation
  25. * is a "combined" view/controller.
  26. *
  27. * @version 1.78 01/23/03
  28. * @author Georges Saab
  29. * @author David Karlton
  30. * @author Arnaud Weber
  31. */
  32. public class BasicMenuBarUI extends MenuBarUI {
  33. protected JMenuBar menuBar = null;
  34. protected ContainerListener containerListener;
  35. protected ChangeListener changeListener;
  36. private PropertyChangeListener propertyChangeListener;
  37. public static ComponentUI createUI(JComponent x) {
  38. return new BasicMenuBarUI();
  39. }
  40. public void installUI(JComponent c) {
  41. menuBar = (JMenuBar) c;
  42. installDefaults();
  43. installListeners();
  44. installKeyboardActions();
  45. }
  46. protected void installDefaults() {
  47. if (menuBar.getLayout() == null ||
  48. menuBar.getLayout() instanceof UIResource) {
  49. menuBar.setLayout(new DefaultMenuLayout(menuBar,BoxLayout.LINE_AXIS));
  50. }
  51. menuBar.setOpaque(true);
  52. LookAndFeel.installBorder(menuBar,"MenuBar.border");
  53. LookAndFeel.installColorsAndFont(menuBar,
  54. "MenuBar.background",
  55. "MenuBar.foreground",
  56. "MenuBar.font");
  57. }
  58. protected void installListeners() {
  59. containerListener = createContainerListener();
  60. changeListener = createChangeListener();
  61. propertyChangeListener = createPropertyChangeListener();
  62. for (int i = 0; i < menuBar.getMenuCount(); i++) {
  63. JMenu menu = menuBar.getMenu(i);
  64. if (menu!=null)
  65. menu.getModel().addChangeListener(changeListener);
  66. }
  67. menuBar.addContainerListener(containerListener);
  68. menuBar.addPropertyChangeListener(propertyChangeListener);
  69. }
  70. protected void installKeyboardActions() {
  71. InputMap inputMap = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
  72. SwingUtilities.replaceUIInputMap(menuBar,
  73. JComponent.WHEN_IN_FOCUSED_WINDOW, inputMap);
  74. ActionMap actionMap = getActionMap();
  75. SwingUtilities.replaceUIActionMap(menuBar, actionMap);
  76. }
  77. InputMap getInputMap(int condition) {
  78. if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) {
  79. Object[] bindings = (Object[])UIManager.get
  80. ("MenuBar.windowBindings");
  81. if (bindings != null) {
  82. return LookAndFeel.makeComponentInputMap(menuBar, bindings);
  83. }
  84. }
  85. return null;
  86. }
  87. ActionMap getActionMap() {
  88. ActionMap map = (ActionMap)UIManager.get("MenuBar.actionMap");
  89. if (map == null) {
  90. map = createActionMap();
  91. if (map != null) {
  92. UIManager.getLookAndFeelDefaults().put("MenuBar.actionMap",
  93. map);
  94. }
  95. }
  96. return map;
  97. }
  98. ActionMap createActionMap() {
  99. ActionMap map = new ActionMapUIResource();
  100. map.put("takeFocus", new TakeFocus());
  101. return map;
  102. }
  103. public void uninstallUI(JComponent c) {
  104. uninstallDefaults();
  105. uninstallListeners();
  106. uninstallKeyboardActions();
  107. menuBar = null;
  108. }
  109. protected void uninstallDefaults() {
  110. if (menuBar!=null) {
  111. LookAndFeel.uninstallBorder(menuBar);
  112. }
  113. }
  114. protected void uninstallListeners() {
  115. menuBar.removeContainerListener(containerListener);
  116. menuBar.removePropertyChangeListener(propertyChangeListener);
  117. for (int i = 0; i < menuBar.getMenuCount(); i++) {
  118. JMenu menu = menuBar.getMenu(i);
  119. if (menu !=null)
  120. menu.getModel().removeChangeListener(changeListener);
  121. }
  122. containerListener = null;
  123. changeListener = null;
  124. propertyChangeListener = null;
  125. }
  126. protected void uninstallKeyboardActions() {
  127. SwingUtilities.replaceUIInputMap(menuBar, JComponent.
  128. WHEN_IN_FOCUSED_WINDOW, null);
  129. SwingUtilities.replaceUIActionMap(menuBar, null);
  130. }
  131. protected ContainerListener createContainerListener() {
  132. return new ContainerHandler();
  133. }
  134. protected ChangeListener createChangeListener() {
  135. return new ChangeHandler();
  136. }
  137. private PropertyChangeListener createPropertyChangeListener() {
  138. return new PropertyChangeHandler();
  139. }
  140. private class ChangeHandler implements ChangeListener {
  141. public void stateChanged(ChangeEvent e) {
  142. int i,c;
  143. for(i=0,c = menuBar.getMenuCount() ; i < c ; i++) {
  144. JMenu menu = menuBar.getMenu(i);
  145. if(menu !=null && menu.isSelected()) {
  146. menuBar.getSelectionModel().setSelectedIndex(i);
  147. break;
  148. }
  149. }
  150. }
  151. }
  152. /*
  153. * This PropertyChangeListener is used to adjust the default layout
  154. * manger when the menuBar is given a right-to-left ComponentOrientation.
  155. * This is a hack to work around the fact that the DefaultMenuLayout
  156. * (BoxLayout) isn't aware of ComponentOrientation. When BoxLayout is
  157. * made aware of ComponentOrientation, this listener will no longer be
  158. * necessary.
  159. */
  160. private class PropertyChangeHandler implements PropertyChangeListener {
  161. public void propertyChange(PropertyChangeEvent e) {
  162. String name = e.getPropertyName();
  163. if( name.equals("componentOrientation")
  164. && (menuBar.getLayout() instanceof UIResource) )
  165. {
  166. menuBar.setLayout(new DefaultMenuLayout(menuBar,BoxLayout.LINE_AXIS));
  167. }
  168. }
  169. }
  170. public Dimension getPreferredSize(JComponent c) {
  171. return null;
  172. }
  173. public Dimension getMinimumSize(JComponent c) {
  174. return null;
  175. }
  176. public Dimension getMaximumSize(JComponent c) {
  177. return null;
  178. }
  179. private class ContainerHandler implements ContainerListener {
  180. public void componentAdded(ContainerEvent e) {
  181. Component c = e.getChild();
  182. if (c instanceof JMenu)
  183. ((JMenu)c).getModel().addChangeListener(changeListener);
  184. }
  185. public void componentRemoved(ContainerEvent e) {
  186. Component c = e.getChild();
  187. if (c instanceof JMenu)
  188. ((JMenu)c).getModel().removeChangeListener(changeListener);
  189. }
  190. }
  191. private static class TakeFocus extends AbstractAction {
  192. TakeFocus() {
  193. }
  194. public void actionPerformed(ActionEvent e) {
  195. JMenuBar menuBar = (JMenuBar)e.getSource();
  196. MenuSelectionManager defaultManager = MenuSelectionManager.defaultManager();
  197. MenuElement me[];
  198. MenuElement subElements[];
  199. JMenu menu = menuBar.getMenu(0);
  200. if (menu!=null) {
  201. me = new MenuElement[3];
  202. me[0] = (MenuElement) menuBar;
  203. me[1] = (MenuElement) menu;
  204. me[2] = (MenuElement) menu.getPopupMenu();
  205. defaultManager.setSelectedPath(me);
  206. }
  207. }
  208. }
  209. }