/* * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.swing.plaf.basic; import java.awt.*;import java.awt.event.*;import java.beans.PropertyChangeEvent;import java.beans.PropertyChangeListener; import javax.swing.*;import javax.swing.event.*;import javax.swing.plaf.*;import javax.swing.text.View; import sun.swing.*; /** * BasicMenuItem implementation * * @author Georges Saab * @author David Karlton * @author Arnaud Weber * @author Fredrik Lagerblad */public class BasicMenuItemUI extends MenuItemUI{ protected JMenuItem menuItem = null; protected Color selectionBackground; protected Color selectionForeground; protected Color disabledForeground; protected Color acceleratorForeground; protected Color acceleratorSelectionForeground; /** * Accelerator delimiter string, such as {@code '+'} in {@code 'Ctrl+C'}. * @since 1.7 */ protected String acceleratorDelimiter; protected int defaultTextIconGap; protected Font acceleratorFont; protected MouseInputListener mouseInputListener; protected MenuDragMouseListener menuDragMouseListener; protected MenuKeyListener menuKeyListener; /** * <code>PropertyChangeListener</code> returned from * <code>createPropertyChangeListener</code>. You should not * need to access this field, rather if you want to customize the * <code>PropertyChangeListener</code> override * <code>createPropertyChangeListener</code>. * * @since 1.6 * @see #createPropertyChangeListener */ protected PropertyChangeListener propertyChangeListener; // BasicMenuUI also uses this. Handler handler; protected Icon arrowIcon = null; protected Icon checkIcon = null; protected boolean oldBorderPainted; /* diagnostic aids -- should be false for production builds. */ private static final boolean TRACE = false; // trace creates and disposes private static final boolean VERBOSE = false; // show reuse hits/misses private static final boolean DEBUG = false; // show bad params, misc. static void loadActionMap(LazyActionMap map) { // NOTE: BasicMenuUI also calls into this method. map.put(new Actions(Actions.CLICK)); BasicLookAndFeel.installAudioActionMap(map); } public static ComponentUI createUI(JComponent c) { return new BasicMenuItemUI(); } public void installUI(JComponent c) { menuItem = (JMenuItem) c; installDefaults(); installComponents(menuItem); installListeners(); installKeyboardActions(); } protected void installDefaults() { String prefix = getPropertyPrefix(); acceleratorFont = UIManager.getFont("MenuItem.acceleratorFont"); // use default if missing so that BasicMenuItemUI can be used in other // LAFs like Nimbus if (acceleratorFont == null) { acceleratorFont = UIManager.getFont("MenuItem.font"); } Object opaque = UIManager.get(getPropertyPrefix() + ".opaque"); if (opaque != null) { LookAndFeel.installProperty(menuItem, "opaque", opaque); } else { LookAndFeel.installProperty(menuItem, "opaque", Boolean.TRUE); } if(menuItem.getMargin() == null || (menuItem.getMargin() instanceof UIResource)) { menuItem.setMargin(UIManager.getInsets(prefix + ".margin")); } LookAndFeel.installProperty(menuItem, "iconTextGap", Integer.valueOf(4)); defaultTextIconGap = menuItem.getIconTextGap(); LookAndFeel.installBorder(menuItem, prefix + ".border"); oldBorderPainted = menuItem.isBorderPainted(); LookAndFeel.installProperty(menuItem, "borderPainted", UIManager.getBoolean(prefix + ".borderPainted")); LookAndFeel.installColorsAndFont(menuItem, prefix + ".background", prefix + ".foreground", prefix + ".font"); // MenuItem specific defaults if (selectionBackground == null || selectionBackground instanceof UIResource) { selectionBackground = UIManager.getColor(prefix + ".selectionBackground"); } if (selectionForeground == null || selectionForeground instanceof UIResource) { selectionForeground = UIManager.getColor(prefix + ".selectionForeground"); } if (disabledForeground == null || disabledForeground instanceof UIResource) { disabledForeground = UIManager.getColor(prefix + ".disabledForeground"); } if (acceleratorForeground == null || acceleratorForeground instanceof UIResource) { acceleratorForeground = UIManager.getColor(prefix + ".acceleratorForeground"); } if (acceleratorSelectionForeground == null || acceleratorSelectionForeground instanceof UIResource) { acceleratorSelectionForeground = UIManager.getColor(prefix + ".acceleratorSelectionForeground"); } // Get accelerator delimiter acceleratorDelimiter = UIManager.getString("MenuItem.acceleratorDelimiter"); if (acceleratorDelimiter == null) { acceleratorDelimiter = "+"; } // Icons if (arrowIcon == null || arrowIcon instanceof UIResource) { arrowIcon = UIManager.getIcon(prefix + ".arrowIcon"); } if (checkIcon == null || checkIcon instanceof UIResource) { checkIcon = UIManager.getIcon(prefix + ".checkIcon"); //In case of column layout, .checkIconFactory is defined for this UI, //the icon is compatible with it and useCheckAndArrow() is true, //then the icon is handled by the checkIcon. boolean isColumnLayout = MenuItemLayoutHelper.isColumnLayout( BasicGraphicsUtils.isLeftToRight(menuItem), menuItem); if (isColumnLayout) { MenuItemCheckIconFactory iconFactory = (MenuItemCheckIconFactory) UIManager.get(prefix + ".checkIconFactory"); if (iconFactory != null && MenuItemLayoutHelper.useCheckAndArrow(menuItem) && iconFactory.isCompatible(checkIcon, prefix)) { checkIcon = iconFactory.getIcon(menuItem); } } } } /** * @since 1.3 */ protected void installComponents(JMenuItem menuItem){ BasicHTML.updateRenderer(menuItem, menuItem.getText()); } protected String getPropertyPrefix() { return "MenuItem"; } protected void installListeners() { if ((mouseInputListener = createMouseInputListener(menuItem)) != null) { menuItem.addMouseListener(mouseInputListener); menuItem.addMouseMotionListener(mouseInputListener); } if ((menuDragMouseListener = createMenuDragMouseListener(menuItem)) != null) { menuItem.addMenuDragMouseListener(menuDragMouseListener); } if ((menuKeyListener = createMenuKeyListener(menuItem)) != null) { menuItem.addMenuKeyListener(menuKeyListener); } if ((propertyChangeListener = createPropertyChangeListener(menuItem)) != null) { menuItem.addPropertyChangeListener(propertyChangeListener); } } protected void installKeyboardActions() { installLazyActionMap(); updateAcceleratorBinding(); } void installLazyActionMap() { LazyActionMap.installLazyActionMap(menuItem, BasicMenuItemUI.class, getPropertyPrefix() + ".actionMap"); } public void uninstallUI(JComponent c) { menuItem = (JMenuItem)c; uninstallDefaults(); uninstallComponents(menuItem); uninstallListeners(); uninstallKeyboardActions(); MenuItemLayoutHelper.clearUsedParentClientProperties(menuItem); menuItem = null; } protected void uninstallDefaults() { LookAndFeel.uninstallBorder(menuItem); LookAndFeel.installProperty(menuItem, "borderPainted", oldBorderPainted); if (menuItem.getMargin() instanceof UIResource) menuItem.setMargin(null); if (arrowIcon instanceof UIResource) arrowIcon = null; if (checkIcon instanceof UIResource) checkIcon = null; } /** * @since 1.3 */ protected void uninstallComponents(JMenuItem menuItem){ BasicHTML.updateRenderer(menuItem, ""); } protected void uninstallListeners() { if (mouseInputListener != null) { menuItem.removeMouseListener(mouseInputListener); menuItem.removeMouseMotionListener(mouseInputListener); } if (menuDragMouseListener != null) { menuItem.removeMenuDragMouseListener(menuDragMouseListener); } if (menuKeyListener != null) { menuItem.removeMenuKeyListener(menuKeyListener); } if (propertyChangeListener != null) { menuItem.removePropertyChangeListener(propertyChangeListener); } mouseInputListener = null; menuDragMouseListener = null; menuKeyListener = null; propertyChangeListener = null; handler = null; } protected void uninstallKeyboardActions() { SwingUtilities.replaceUIActionMap(menuItem, null); SwingUtilities.replaceUIInputMap(menuItem, JComponent. WHEN_IN_FOCUSED_WINDOW, null); } protected MouseInputListener createMouseInputListener(JComponent c) { return getHandler(); } protected MenuDragMouseListener createMenuDragMouseListener(JComponent c) { return getHandler(); } protected MenuKeyListener createMenuKeyListener(JComponent c) { return null; } /** * Creates a <code>PropertyChangeListener</code> which will be added to * the menu item. * If this method returns null then it will not be added to the menu item. * * @return an instance of a <code>PropertyChangeListener</code> or null * @since 1.6 */ protected PropertyChangeListener createPropertyChangeListener(JComponent c) { return getHandler(); } Handler getHandler() { if (handler == null) { handler = new Handler(); } return handler; } InputMap createInputMap(int condition) { if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) { return new ComponentInputMapUIResource(menuItem); } return null; } void updateAcceleratorBinding() { KeyStroke accelerator = menuItem.getAccelerator(); InputMap windowInputMap = SwingUtilities.getUIInputMap( menuItem, JComponent.WHEN_IN_FOCUSED_WINDOW); if (windowInputMap != null) { windowInputMap.clear(); } if (accelerator != null) { if (windowInputMap == null) { windowInputMap = createInputMap(JComponent. WHEN_IN_FOCUSED_WINDOW); SwingUtilities.replaceUIInputMap(menuItem, JComponent.WHEN_IN_FOCUSED_WINDOW, windowInputMap); } windowInputMap.put(accelerator, "doClick"); } } public Dimension getMinimumSize(JComponent c) { Dimension d = null; View v = (View) c.getClientProperty(BasicHTML.propertyKey); if (v != null) { d = getPreferredSize(c); d.width -= v.getPreferredSpan(View.X_AXIS) - v.getMinimumSpan(View.X_AXIS); } return d; } public Dimension getPreferredSize(JComponent c) { return getPreferredMenuItemSize(c, checkIcon, arrowIcon, defaultTextIconGap); } public Dimension getMaximumSize(JComponent c) { Dimension d = null; View v = (View) c.getClientProperty(BasicHTML.propertyKey); if (v != null) { d = getPreferredSize(c); d.width += v.getMaximumSpan(View.X_AXIS) - v.getPreferredSpan(View.X_AXIS); } return d; } protected Dimension getPreferredMenuItemSize(JComponent c, Icon checkIcon, Icon arrowIcon, int defaultTextIconGap) { // The method also determines the preferred width of the // parent popup menu (through DefaultMenuLayout class). // The menu width equals to the maximal width // among child menu items. // Menu item width will be a sum of the widest check icon, label, // arrow icon and accelerator text among neighbor menu items. // For the latest menu item we will know the maximal widths exactly. // It will be the widest menu item and it will determine // the width of the parent popup menu. // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // There is a conceptual problem: if user sets preferred size manually // for a menu item, this method won't be called for it // (see JComponent.getPreferredSize()), // maximal widths won't be calculated, other menu items won't be able // to take them into account and will be layouted in such a way, // as there is no the item with manual preferred size. // But after the first paint() method call, all maximal widths // will be correctly calculated and layout of some menu items // can be changed. For example, it can cause a shift of // the icon and text when user points a menu item by mouse. JMenuItem mi = (JMenuItem) c; MenuItemLayoutHelper lh = new MenuItemLayoutHelper(mi, checkIcon, arrowIcon, MenuItemLayoutHelper.createMaxRect(), defaultTextIconGap, acceleratorDelimiter, BasicGraphicsUtils.isLeftToRight(mi), mi.getFont(), acceleratorFont, MenuItemLayoutHelper.useCheckAndArrow(menuItem), getPropertyPrefix()); Dimension result = new Dimension(); // Calculate the result width result.width = lh.getLeadingGap(); MenuItemLayoutHelper.addMaxWidth(lh.getCheckSize(), lh.getAfterCheckIconGap(), result); // Take into account mimimal text offset. if ((!lh.isTopLevelMenu()) && (lh.getMinTextOffset() > 0) && (result.width < lh.getMinTextOffset())) { result.width = lh.getMinTextOffset(); } MenuItemLayoutHelper.addMaxWidth(lh.getLabelSize(), lh.getGap(), result); MenuItemLayoutHelper.addMaxWidth(lh.getAccSize(), lh.getGap(), result); MenuItemLayoutHelper.addMaxWidth(lh.getArrowSize(), lh.getGap(), result); // Calculate the result height result.height = MenuItemLayoutHelper.max(lh.getCheckSize().getHeight(), lh.getLabelSize().getHeight(), lh.getAccSize().getHeight(), lh.getArrowSize().getHeight()); // Take into account menu item insets Insets insets = lh.getMenuItem().getInsets(); if(insets != null) { result.width += insets.left + insets.right; result.height += insets.top + insets.bottom; } // if the width is even, bump it up one. This is critical // for the focus dash line to draw properly if(result.width%2 == 0) { result.width++; } // if the height is even, bump it up one. This is critical // for the text to center properly if(result.height%2 == 0 && Boolean.TRUE != UIManager.get(getPropertyPrefix() + ".evenHeight")) { result.height++; } return result; } /** * We draw the background in paintMenuItem() * so override update (which fills the background of opaque * components by default) to just call paint(). * */ public void update(Graphics g, JComponent c) { paint(g, c); } public void paint(Graphics g, JComponent c) { paintMenuItem(g, c, checkIcon, arrowIcon, selectionBackground, selectionForeground, defaultTextIconGap); } protected void paintMenuItem(Graphics g, JComponent c, Icon checkIcon, Icon arrowIcon, Color background, Color foreground, int defaultTextIconGap) { // Save original graphics font and color Font holdf = g.getFont(); Color holdc = g.getColor(); JMenuItem mi = (JMenuItem) c; g.setFont(mi.getFont()); Rectangle viewRect = new Rectangle(0, 0, mi.getWidth(), mi.getHeight()); applyInsets(viewRect, mi.getInsets()); MenuItemLayoutHelper lh = new MenuItemLayoutHelper(mi, checkIcon, arrowIcon, viewRect, defaultTextIconGap, acceleratorDelimiter, BasicGraphicsUtils.isLeftToRight(mi), mi.getFont(), acceleratorFont, MenuItemLayoutHelper.useCheckAndArrow(menuItem), getPropertyPrefix()); MenuItemLayoutHelper.LayoutResult lr = lh.layoutMenuItem(); Lines 1–500 of 972. Load more
/* * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.swing.plaf.basic; import java.awt.*; import java.awt.event.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.*; import javax.swing.event.*; import javax.swing.plaf.*; import javax.swing.text.View; import sun.swing.*; /** * BasicMenuItem implementation * * @author Georges Saab * @author David Karlton * @author Arnaud Weber * @author Fredrik Lagerblad */ public class BasicMenuItemUI extends MenuItemUI { protected JMenuItem menuItem = null; protected Color selectionBackground; protected Color selectionForeground; protected Color disabledForeground; protected Color acceleratorForeground; protected Color acceleratorSelectionForeground; /** * Accelerator delimiter string, such as {@code '+'} in {@code 'Ctrl+C'}. * @since 1.7 */ protected String acceleratorDelimiter; protected int defaultTextIconGap; protected Font acceleratorFont; protected MouseInputListener mouseInputListener; protected MenuDragMouseListener menuDragMouseListener; protected MenuKeyListener menuKeyListener; /** * <code>PropertyChangeListener</code> returned from * <code>createPropertyChangeListener</code>. You should not * need to access this field, rather if you want to customize the * <code>PropertyChangeListener</code> override * <code>createPropertyChangeListener</code>. * * @since 1.6 * @see #createPropertyChangeListener */ protected PropertyChangeListener propertyChangeListener; // BasicMenuUI also uses this. Handler handler; protected Icon arrowIcon = null; protected Icon checkIcon = null; protected boolean oldBorderPainted; /* diagnostic aids -- should be false for production builds. */ private static final boolean TRACE = false; // trace creates and disposes private static final boolean VERBOSE = false; // show reuse hits/misses private static final boolean DEBUG = false; // show bad params, misc. static void loadActionMap(LazyActionMap map) { // NOTE: BasicMenuUI also calls into this method. map.put(new Actions(Actions.CLICK)); BasicLookAndFeel.installAudioActionMap(map); } public static ComponentUI createUI(JComponent c) { return new BasicMenuItemUI(); } public void installUI(JComponent c) { menuItem = (JMenuItem) c; installDefaults(); installComponents(menuItem); installListeners(); installKeyboardActions(); } protected void installDefaults() { String prefix = getPropertyPrefix(); acceleratorFont = UIManager.getFont("MenuItem.acceleratorFont"); // use default if missing so that BasicMenuItemUI can be used in other // LAFs like Nimbus if (acceleratorFont == null) { acceleratorFont = UIManager.getFont("MenuItem.font"); } Object opaque = UIManager.get(getPropertyPrefix() + ".opaque"); if (opaque != null) { LookAndFeel.installProperty(menuItem, "opaque", opaque); } else { LookAndFeel.installProperty(menuItem, "opaque", Boolean.TRUE); } if(menuItem.getMargin() == null || (menuItem.getMargin() instanceof UIResource)) { menuItem.setMargin(UIManager.getInsets(prefix + ".margin")); } LookAndFeel.installProperty(menuItem, "iconTextGap", Integer.valueOf(4)); defaultTextIconGap = menuItem.getIconTextGap(); LookAndFeel.installBorder(menuItem, prefix + ".border"); oldBorderPainted = menuItem.isBorderPainted(); LookAndFeel.installProperty(menuItem, "borderPainted", UIManager.getBoolean(prefix + ".borderPainted")); LookAndFeel.installColorsAndFont(menuItem, prefix + ".background", prefix + ".foreground", prefix + ".font"); // MenuItem specific defaults if (selectionBackground == null || selectionBackground instanceof UIResource) { selectionBackground = UIManager.getColor(prefix + ".selectionBackground"); } if (selectionForeground == null || selectionForeground instanceof UIResource) { selectionForeground = UIManager.getColor(prefix + ".selectionForeground"); } if (disabledForeground == null || disabledForeground instanceof UIResource) { disabledForeground = UIManager.getColor(prefix + ".disabledForeground"); } if (acceleratorForeground == null || acceleratorForeground instanceof UIResource) { acceleratorForeground = UIManager.getColor(prefix + ".acceleratorForeground"); } if (acceleratorSelectionForeground == null || acceleratorSelectionForeground instanceof UIResource) { acceleratorSelectionForeground = UIManager.getColor(prefix + ".acceleratorSelectionForeground"); } // Get accelerator delimiter acceleratorDelimiter = UIManager.getString("MenuItem.acceleratorDelimiter"); if (acceleratorDelimiter == null) { acceleratorDelimiter = "+"; } // Icons if (arrowIcon == null || arrowIcon instanceof UIResource) { arrowIcon = UIManager.getIcon(prefix + ".arrowIcon"); } if (checkIcon == null || checkIcon instanceof UIResource) { checkIcon = UIManager.getIcon(prefix + ".checkIcon"); //In case of column layout, .checkIconFactory is defined for this UI, //the icon is compatible with it and useCheckAndArrow() is true, //then the icon is handled by the checkIcon. boolean isColumnLayout = MenuItemLayoutHelper.isColumnLayout( BasicGraphicsUtils.isLeftToRight(menuItem), menuItem); if (isColumnLayout) { MenuItemCheckIconFactory iconFactory = (MenuItemCheckIconFactory) UIManager.get(prefix + ".checkIconFactory"); if (iconFactory != null && MenuItemLayoutHelper.useCheckAndArrow(menuItem) && iconFactory.isCompatible(checkIcon, prefix)) { checkIcon = iconFactory.getIcon(menuItem); } } } } /** * @since 1.3 */ protected void installComponents(JMenuItem menuItem){ BasicHTML.updateRenderer(menuItem, menuItem.getText()); } protected String getPropertyPrefix() { return "MenuItem"; } protected void installListeners() { if ((mouseInputListener = createMouseInputListener(menuItem)) != null) { menuItem.addMouseListener(mouseInputListener); menuItem.addMouseMotionListener(mouseInputListener); } if ((menuDragMouseListener = createMenuDragMouseListener(menuItem)) != null) { menuItem.addMenuDragMouseListener(menuDragMouseListener); } if ((menuKeyListener = createMenuKeyListener(menuItem)) != null) { menuItem.addMenuKeyListener(menuKeyListener); } if ((propertyChangeListener = createPropertyChangeListener(menuItem)) != null) { menuItem.addPropertyChangeListener(propertyChangeListener); } } protected void installKeyboardActions() { installLazyActionMap(); updateAcceleratorBinding(); } void installLazyActionMap() { LazyActionMap.installLazyActionMap(menuItem, BasicMenuItemUI.class, getPropertyPrefix() + ".actionMap"); } public void uninstallUI(JComponent c) { menuItem = (JMenuItem)c; uninstallDefaults(); uninstallComponents(menuItem); uninstallListeners(); uninstallKeyboardActions(); MenuItemLayoutHelper.clearUsedParentClientProperties(menuItem); menuItem = null; } protected void uninstallDefaults() { LookAndFeel.uninstallBorder(menuItem); LookAndFeel.installProperty(menuItem, "borderPainted", oldBorderPainted); if (menuItem.getMargin() instanceof UIResource) menuItem.setMargin(null); if (arrowIcon instanceof UIResource) arrowIcon = null; if (checkIcon instanceof UIResource) checkIcon = null; } /** * @since 1.3 */ protected void uninstallComponents(JMenuItem menuItem){ BasicHTML.updateRenderer(menuItem, ""); } protected void uninstallListeners() { if (mouseInputListener != null) { menuItem.removeMouseListener(mouseInputListener); menuItem.removeMouseMotionListener(mouseInputListener); } if (menuDragMouseListener != null) { menuItem.removeMenuDragMouseListener(menuDragMouseListener); } if (menuKeyListener != null) { menuItem.removeMenuKeyListener(menuKeyListener); } if (propertyChangeListener != null) { menuItem.removePropertyChangeListener(propertyChangeListener); } mouseInputListener = null; menuDragMouseListener = null; menuKeyListener = null; propertyChangeListener = null; handler = null; } protected void uninstallKeyboardActions() { SwingUtilities.replaceUIActionMap(menuItem, null); SwingUtilities.replaceUIInputMap(menuItem, JComponent. WHEN_IN_FOCUSED_WINDOW, null); } protected MouseInputListener createMouseInputListener(JComponent c) { return getHandler(); } protected MenuDragMouseListener createMenuDragMouseListener(JComponent c) { return getHandler(); } protected MenuKeyListener createMenuKeyListener(JComponent c) { return null; } /** * Creates a <code>PropertyChangeListener</code> which will be added to * the menu item. * If this method returns null then it will not be added to the menu item. * * @return an instance of a <code>PropertyChangeListener</code> or null * @since 1.6 */ protected PropertyChangeListener createPropertyChangeListener(JComponent c) { return getHandler(); } Handler getHandler() { if (handler == null) { handler = new Handler(); } return handler; } InputMap createInputMap(int condition) { if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) { return new ComponentInputMapUIResource(menuItem); } return null; } void updateAcceleratorBinding() { KeyStroke accelerator = menuItem.getAccelerator(); InputMap windowInputMap = SwingUtilities.getUIInputMap( menuItem, JComponent.WHEN_IN_FOCUSED_WINDOW); if (windowInputMap != null) { windowInputMap.clear(); } if (accelerator != null) { if (windowInputMap == null) { windowInputMap = createInputMap(JComponent. WHEN_IN_FOCUSED_WINDOW); SwingUtilities.replaceUIInputMap(menuItem, JComponent.WHEN_IN_FOCUSED_WINDOW, windowInputMap); } windowInputMap.put(accelerator, "doClick"); } } public Dimension getMinimumSize(JComponent c) { Dimension d = null; View v = (View) c.getClientProperty(BasicHTML.propertyKey); if (v != null) { d = getPreferredSize(c); d.width -= v.getPreferredSpan(View.X_AXIS) - v.getMinimumSpan(View.X_AXIS); } return d; } public Dimension getPreferredSize(JComponent c) { return getPreferredMenuItemSize(c, checkIcon, arrowIcon, defaultTextIconGap); } public Dimension getMaximumSize(JComponent c) { Dimension d = null; View v = (View) c.getClientProperty(BasicHTML.propertyKey); if (v != null) { d = getPreferredSize(c); d.width += v.getMaximumSpan(View.X_AXIS) - v.getPreferredSpan(View.X_AXIS); } return d; } protected Dimension getPreferredMenuItemSize(JComponent c, Icon checkIcon, Icon arrowIcon, int defaultTextIconGap) { // The method also determines the preferred width of the // parent popup menu (through DefaultMenuLayout class). // The menu width equals to the maximal width // among child menu items. // Menu item width will be a sum of the widest check icon, label, // arrow icon and accelerator text among neighbor menu items. // For the latest menu item we will know the maximal widths exactly. // It will be the widest menu item and it will determine // the width of the parent popup menu. // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // There is a conceptual problem: if user sets preferred size manually // for a menu item, this method won't be called for it // (see JComponent.getPreferredSize()), // maximal widths won't be calculated, other menu items won't be able // to take them into account and will be layouted in such a way, // as there is no the item with manual preferred size. // But after the first paint() method call, all maximal widths // will be correctly calculated and layout of some menu items // can be changed. For example, it can cause a shift of // the icon and text when user points a menu item by mouse. JMenuItem mi = (JMenuItem) c; MenuItemLayoutHelper lh = new MenuItemLayoutHelper(mi, checkIcon, arrowIcon, MenuItemLayoutHelper.createMaxRect(), defaultTextIconGap, acceleratorDelimiter, BasicGraphicsUtils.isLeftToRight(mi), mi.getFont(), acceleratorFont, MenuItemLayoutHelper.useCheckAndArrow(menuItem), getPropertyPrefix()); Dimension result = new Dimension(); // Calculate the result width result.width = lh.getLeadingGap(); MenuItemLayoutHelper.addMaxWidth(lh.getCheckSize(), lh.getAfterCheckIconGap(), result); // Take into account mimimal text offset. if ((!lh.isTopLevelMenu()) && (lh.getMinTextOffset() > 0) && (result.width < lh.getMinTextOffset())) { result.width = lh.getMinTextOffset(); } MenuItemLayoutHelper.addMaxWidth(lh.getLabelSize(), lh.getGap(), result); MenuItemLayoutHelper.addMaxWidth(lh.getAccSize(), lh.getGap(), result); MenuItemLayoutHelper.addMaxWidth(lh.getArrowSize(), lh.getGap(), result); // Calculate the result height result.height = MenuItemLayoutHelper.max(lh.getCheckSize().getHeight(), lh.getLabelSize().getHeight(), lh.getAccSize().getHeight(), lh.getArrowSize().getHeight()); // Take into account menu item insets Insets insets = lh.getMenuItem().getInsets(); if(insets != null) { result.width += insets.left + insets.right; result.height += insets.top + insets.bottom; } // if the width is even, bump it up one. This is critical // for the focus dash line to draw properly if(result.width%2 == 0) { result.width++; } // if the height is even, bump it up one. This is critical // for the text to center properly if(result.height%2 == 0 && Boolean.TRUE != UIManager.get(getPropertyPrefix() + ".evenHeight")) { result.height++; } return result; } /** * We draw the background in paintMenuItem() * so override update (which fills the background of opaque * components by default) to just call paint(). * */ public void update(Graphics g, JComponent c) { paint(g, c); } public void paint(Graphics g, JComponent c) { paintMenuItem(g, c, checkIcon, arrowIcon, selectionBackground, selectionForeground, defaultTextIconGap); } protected void paintMenuItem(Graphics g, JComponent c, Icon checkIcon, Icon arrowIcon, Color background, Color foreground, int defaultTextIconGap) { // Save original graphics font and color Font holdf = g.getFont(); Color holdc = g.getColor(); JMenuItem mi = (JMenuItem) c; g.setFont(mi.getFont()); Rectangle viewRect = new Rectangle(0, 0, mi.getWidth(), mi.getHeight()); applyInsets(viewRect, mi.getInsets()); MenuItemLayoutHelper lh = new MenuItemLayoutHelper(mi, checkIcon, arrowIcon, viewRect, defaultTextIconGap, acceleratorDelimiter, BasicGraphicsUtils.isLeftToRight(mi), mi.getFont(), acceleratorFont, MenuItemLayoutHelper.useCheckAndArrow(menuItem), getPropertyPrefix()); MenuItemLayoutHelper.LayoutResult lr = lh.layoutMenuItem();