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