1. /*
  2. * @(#)SynthMenuBarUI.java 1.7 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 com.sun.java.swing.plaf.gtk;
  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.7, 01/23/03 (based on BasicMenuBarUI v 1.77)
  28. * @author Georges Saab
  29. * @author David Karlton
  30. * @author Arnaud Weber
  31. */
  32. class SynthMenuBarUI extends MenuBarUI implements SynthUI {
  33. protected JMenuBar menuBar = null;
  34. protected ContainerListener containerListener;
  35. protected ChangeListener changeListener;
  36. private PropertyChangeListener propertyChangeListener;
  37. private SynthStyle style;
  38. public static ComponentUI createUI(JComponent x) {
  39. return new SynthMenuBarUI();
  40. }
  41. public static void loadActionMap(ActionMap map) {
  42. // NOTE: this needs to remain static. If you have a need to
  43. // have Actions that reference the UI in the ActionMap,
  44. // then you'll also need to change the registeration of the
  45. // ActionMap.
  46. map.put("takeFocus", new TakeFocus());
  47. }
  48. public void installUI(JComponent c) {
  49. menuBar = (JMenuBar) c;
  50. installDefaults();
  51. installListeners();
  52. installKeyboardActions();
  53. }
  54. protected void installDefaults() {
  55. if (menuBar.getLayout() == null ||
  56. menuBar.getLayout() instanceof UIResource) {
  57. menuBar.setLayout(new DefaultMenuLayout(menuBar,BoxLayout.LINE_AXIS));
  58. }
  59. fetchStyle(menuBar);
  60. }
  61. private void fetchStyle(JMenuBar c) {
  62. SynthContext context = getContext(c, ENABLED);
  63. style = SynthLookAndFeel.updateStyle(context, this);
  64. context.dispose();
  65. }
  66. protected void installListeners() {
  67. containerListener = createContainerListener();
  68. changeListener = createChangeListener();
  69. propertyChangeListener = createPropertyChangeListener();
  70. for (int i = 0; i < menuBar.getMenuCount(); i++) {
  71. JMenu menu = menuBar.getMenu(i);
  72. if (menu!=null)
  73. menu.getModel().addChangeListener(changeListener);
  74. }
  75. menuBar.addContainerListener(containerListener);
  76. menuBar.addPropertyChangeListener(propertyChangeListener);
  77. }
  78. protected void installKeyboardActions() {
  79. InputMap inputMap = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
  80. SwingUtilities.replaceUIInputMap(menuBar,
  81. JComponent.WHEN_IN_FOCUSED_WINDOW, inputMap);
  82. LazyActionMap.installLazyActionMap(menuBar, SynthMenuBarUI.class,
  83. "MenuBar.actionMap");
  84. }
  85. InputMap getInputMap(int condition) {
  86. if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) {
  87. SynthContext context = getContext(menuBar, ENABLED);
  88. Object[] bindings = (Object[])context.getStyle().get(context,
  89. "MenuBar.windowBindings");
  90. InputMap map;
  91. if (bindings != null) {
  92. map = LookAndFeel.makeComponentInputMap(menuBar, bindings);
  93. }
  94. else {
  95. map = null;
  96. }
  97. context.dispose();
  98. return map;
  99. }
  100. return null;
  101. }
  102. public void uninstallUI(JComponent c) {
  103. uninstallDefaults();
  104. uninstallListeners();
  105. uninstallKeyboardActions();
  106. menuBar = null;
  107. }
  108. protected void uninstallDefaults() {
  109. SynthContext context = getContext(menuBar, ENABLED);
  110. style.uninstallDefaults(context);
  111. context.dispose();
  112. style = null;
  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. public SynthContext getContext(JComponent c) {
  141. return getContext(c, getComponentState(c));
  142. }
  143. private SynthContext getContext(JComponent c, int state) {
  144. return SynthContext.getContext(SynthContext.class, c,
  145. SynthLookAndFeel.getRegion(c), style, state);
  146. }
  147. private Region getRegion(JComponent c) {
  148. return SynthLookAndFeel.getRegion(c);
  149. }
  150. private int getComponentState(JComponent c) {
  151. return SynthLookAndFeel.getComponentState(c);
  152. }
  153. public void update(Graphics g, JComponent c) {
  154. SynthContext context = getContext(c);
  155. SynthLookAndFeel.update(context, g);
  156. paint(context, g);
  157. context.dispose();
  158. }
  159. public void paint(Graphics g, JComponent c) {
  160. SynthContext context = getContext(c);
  161. paint(context, g);
  162. context.dispose();
  163. }
  164. protected void paint(SynthContext context, Graphics g) {
  165. }
  166. private class ChangeHandler implements ChangeListener {
  167. public void stateChanged(ChangeEvent e) {
  168. int i,c;
  169. for(i=0,c = menuBar.getMenuCount() ; i < c ; i++) {
  170. JMenu menu = menuBar.getMenu(i);
  171. if(menu !=null && menu.isSelected()) {
  172. menuBar.getSelectionModel().setSelectedIndex(i);
  173. break;
  174. }
  175. }
  176. }
  177. }
  178. /*
  179. * This PropertyChangeListener is used to adjust the default layout
  180. * manger when the menuBar is given a right-to-left ComponentOrientation.
  181. * This is a hack to work around the fact that the DefaultMenuLayout
  182. * (BoxLayout) isn't aware of ComponentOrientation. When BoxLayout is
  183. * made aware of ComponentOrientation, this listener will no longer be
  184. * necessary.
  185. */
  186. private class PropertyChangeHandler implements PropertyChangeListener {
  187. public void propertyChange(PropertyChangeEvent e) {
  188. String name = e.getPropertyName();
  189. if (SynthLookAndFeel.shouldUpdateStyle(e)) {
  190. fetchStyle((JMenuBar)e.getSource());
  191. }
  192. if( name.equals("componentOrientation")
  193. && (menuBar.getLayout() instanceof UIResource) )
  194. {
  195. menuBar.setLayout(new DefaultMenuLayout(menuBar,BoxLayout.LINE_AXIS));
  196. }
  197. }
  198. }
  199. public Dimension getPreferredSize(JComponent c) {
  200. return null;
  201. }
  202. public Dimension getMinimumSize(JComponent c) {
  203. return null;
  204. }
  205. public Dimension getMaximumSize(JComponent c) {
  206. return null;
  207. }
  208. private class ContainerHandler implements ContainerListener {
  209. public void componentAdded(ContainerEvent e) {
  210. Component c = e.getChild();
  211. if (c instanceof JMenu)
  212. ((JMenu)c).getModel().addChangeListener(changeListener);
  213. }
  214. public void componentRemoved(ContainerEvent e) {
  215. Component c = e.getChild();
  216. if (c instanceof JMenu)
  217. ((JMenu)c).getModel().removeChangeListener(changeListener);
  218. }
  219. }
  220. private static class TakeFocus extends AbstractAction {
  221. TakeFocus() {
  222. }
  223. public void actionPerformed(ActionEvent e) {
  224. JMenuBar menuBar = (JMenuBar)e.getSource();
  225. MenuSelectionManager defaultManager = MenuSelectionManager.defaultManager();
  226. MenuElement me[];
  227. MenuElement subElements[];
  228. JMenu menu = menuBar.getMenu(0);
  229. if (menu!=null) {
  230. me = new MenuElement[3];
  231. me[0] = (MenuElement) menuBar;
  232. me[1] = (MenuElement) menu;
  233. me[2] = (MenuElement) menu.getPopupMenu();
  234. defaultManager.setSelectedPath(me);
  235. }
  236. }
  237. }
  238. }