📄 menuitemui.java
字号:
package com.digitprop.tonic;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.*;
import javax.swing.plaf.basic.*;
import javax.swing.text.View;
/** UI delegate for JMenuItems.
*
* @author Markus Fischer
*
* <p>This software is under the <a href="http://www.gnu.org/copyleft/lesser.html" target="_blank">GNU Lesser General Public License</a>
*/
/*
* ------------------------------------------------------------------------
* Copyright (C) 2004 Markus Fischer
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* You can contact the author at:
* Markus Fischer
* www.digitprop.com
* info@digitprop.com
* ------------------------------------------------------------------------
*/
public class MenuItemUI extends BasicMenuItemUI
{
/** Used for painting and preferred size calculations */
static Rectangle zeroRect= new Rectangle(0, 0, 0, 0);
/** Used for painting and preferred size calculations */
static Rectangle iconRect= new Rectangle();
/** Used for painting and preferred size calculations */
static Rectangle textRect= new Rectangle();
/** Used for painting and preferred size calculations */
static Rectangle acceleratorRect= new Rectangle();
/** Used for painting and preferred size calculations */
static Rectangle checkIconRect= new Rectangle();
/** Used for painting and preferred size calculations */
static Rectangle arrowIconRect= new Rectangle();
/** Used for painting and preferred size calculations */
static Rectangle viewRect= new Rectangle(Short.MAX_VALUE, Short.MAX_VALUE);
/** Used for painting and preferred size calculations */
static Rectangle r= new Rectangle();
/** The associated menu item */
protected JMenuItem menuItem= null;
/** Color of the selected background */
protected Color selectionBackground;
/** Foreground color for selected items */
protected Color selectionForeground;
/** Foreground color for disabled items */
protected Color disabledForeground;
/** Foreground color for accelerators */
protected Color acceleratorForeground;
/** Foreground color for selected accelerators */
protected Color acceleratorSelectionForeground;
/** Delimiting string for accelerators */
private String acceleratorDelimiter;
/** Gap between text and icon */
protected int defaultTextIconGap;
/** Font for accelerators */
protected Font acceleratorFont;
/** Associated mouse input listener */
protected MouseInputListener mouseInputListener;
/** Associated mouse listener */
protected MenuDragMouseListener menuDragMouseListener;
/** Associated key listener */
protected MenuKeyListener menuKeyListener;
/** Associated property change listener */
private PropertyChangeListener propertyChangeListener;
/** Arrow icon */
protected Icon arrowIcon= null;
/** Inverted arrow icon (for selected menu items) */
protected Icon invArrowIcon= null;
/** Checked icon (for checkbox menu items) */
protected Icon checkIcon= null;
/** Unchecked icon (for checkbox menu items) */
protected Icon uncheckIcon=null;
/** ? */
protected boolean oldBorderPainted;
/** Used for accelerator binding, lazily created. */
InputMap windowInputMap;
/** Diagnostic aids -- should be false for production builds. */
private static final boolean TRACE= false; // trace creates and disposes
/** Diagnostic aids -- should be false for production builds. */
private static final boolean VERBOSE= false; // show reuse hits/misses
/** Diagnostic aids -- should be false for production builds. */
private static final boolean DEBUG= false; // show bad params, misc.
/** Client Property keys for text and accelerator text widths */
static final String MAX_TEXT_WIDTH= "maxTextWidth";
/** Client Property keys for text and accelerator text widths */
static final String MAX_ACC_WIDTH= "maxAccWidth";
/** Creates and returns the UI delegate for the specified component */
public static ComponentUI createUI(JComponent c)
{
return new MenuItemUI();
}
/** Installs the UI delegate for the specified component */
public void installUI(JComponent c)
{
menuItem= (JMenuItem) c;
installDefaults();
installComponents(menuItem);
installListeners();
installKeyboardActions();
}
/** Installs defaults settings for the associated menu item */
protected void installDefaults()
{
String prefix= getPropertyPrefix();
acceleratorFont= UIManager.getFont("MenuItem.acceleratorFont");
menuItem.setOpaque(true);
if (menuItem.getMargin() == null
|| (menuItem.getMargin() instanceof UIResource))
{
menuItem.setMargin(UIManager.getInsets(prefix + ".margin"));
}
defaultTextIconGap= 4; // Should be from table
LookAndFeel.installBorder(menuItem, prefix + ".border");
oldBorderPainted= menuItem.isBorderPainted();
menuItem.setBorderPainted(
((Boolean) (UIManager.get(prefix + ".borderPainted"))).booleanValue());
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 (invArrowIcon == null || invArrowIcon instanceof UIResource)
{
invArrowIcon= UIManager.getIcon(prefix + ".invArrowIcon");
}
if (checkIcon == null || checkIcon instanceof UIResource)
{
checkIcon= UIManager.getIcon(prefix + ".checkIcon");
}
if (uncheckIcon == null || uncheckIcon instanceof UIResource)
{
uncheckIcon= UIManager.getIcon(prefix + ".uncheckIcon");
}
}
/** Installs components to the specified menu item */
protected void installComponents(JMenuItem menuItem)
{
BasicHTML.updateRenderer(menuItem, menuItem.getText());
}
/** Returns the property prefix for menu items */
protected String getPropertyPrefix()
{
return "MenuItem";
}
/** Installs listeners for the associated menu item */
protected void installListeners()
{
mouseInputListener= createMouseInputListener(menuItem);
menuDragMouseListener= createMenuDragMouseListener(menuItem);
menuKeyListener= createMenuKeyListener(menuItem);
propertyChangeListener= createPropertyChangeListener(menuItem);
menuItem.addMouseListener(mouseInputListener);
menuItem.addMouseMotionListener(mouseInputListener);
menuItem.addMenuDragMouseListener(menuDragMouseListener);
menuItem.addMenuKeyListener(menuKeyListener);
menuItem.addPropertyChangeListener(propertyChangeListener);
}
/** Installs keyboard actions for the associated menu item */
protected void installKeyboardActions()
{
ActionMap actionMap= getMyActionMap();
SwingUtilities.replaceUIActionMap(menuItem, actionMap);
updateMyAcceleratorBinding();
}
/** Uninstalls the UI delegate for the specified component */
public void uninstallUI(JComponent c)
{
menuItem= (JMenuItem) c;
uninstallDefaults();
uninstallComponents(menuItem);
uninstallListeners();
uninstallKeyboardActions();
//Remove the textWidth and accWidth values from the parent's Client Properties.
Container parent= menuItem.getParent();
if ((parent != null && parent instanceof JComponent)
&& !(menuItem instanceof JMenu && ((JMenu) menuItem).isTopLevelMenu()))
{
JComponent p= (JComponent) parent;
p.putClientProperty(MAX_ACC_WIDTH, null);
p.putClientProperty(MAX_TEXT_WIDTH, null);
}
menuItem= null;
}
/** Uninstalls the defaults from the associated menu item */
protected void uninstallDefaults()
{
LookAndFeel.uninstallBorder(menuItem);
menuItem.setBorderPainted(oldBorderPainted);
if (menuItem.getMargin() instanceof UIResource)
menuItem.setMargin(null);
if (arrowIcon instanceof UIResource)
arrowIcon= null;
if (checkIcon instanceof UIResource)
checkIcon= null;
}
/** Uninstalls additional components added to the menu item upon installation */
protected void uninstallComponents(JMenuItem menuItem)
{
BasicHTML.updateRenderer(menuItem, "");
}
/** Uninstalls any registered listeners from the associated menu item */
protected void uninstallListeners()
{
menuItem.removeMouseListener(mouseInputListener);
menuItem.removeMouseMotionListener(mouseInputListener);
menuItem.removeMenuDragMouseListener(menuDragMouseListener);
menuItem.removeMenuKeyListener(menuKeyListener);
menuItem.removePropertyChangeListener(propertyChangeListener);
mouseInputListener= null;
menuDragMouseListener= null;
menuKeyListener= null;
propertyChangeListener= null;
}
/** Uninstalls any keyboard actions from the associated menu item */
protected void uninstallKeyboardActions()
{
SwingUtilities.replaceUIActionMap(menuItem, null);
if (windowInputMap != null)
{
SwingUtilities.replaceUIInputMap(
menuItem,
JComponent.WHEN_IN_FOCUSED_WINDOW,
null);
windowInputMap= null;
}
}
/** Creates and returns a mouse input listener for the specified component */
protected MouseInputListener createMouseInputListener(JComponent c)
{
return new MouseInputHandler();
}
/** Creates and returns a mouse listener for the specified component */
protected MenuDragMouseListener createMenuDragMouseListener(JComponent c)
{
return new MenuDragMouseHandler();
}
/** Creates and returns a key listener for the specified component */
protected MenuKeyListener createMenuKeyListener(JComponent c)
{
return new MenuKeyHandler();
}
/** Creates and returns a property change listener for the specified component */
private PropertyChangeListener createPropertyChangeListener(JComponent c)
{
return new PropertyChangeHandler();
}
/** Returns the action map to be associated with the underlying menu item */
ActionMap getMyActionMap()
{
String propertyPrefix= getPropertyPrefix();
String uiKey= propertyPrefix + ".actionMap";
ActionMap am= (ActionMap) UIManager.get(uiKey);
if (am == null)
{
am= createMyActionMap();
UIManager.getLookAndFeelDefaults().put(uiKey, am);
}
return am;
}
/** Creates an action map for associated menu items */
ActionMap createMyActionMap()
{
ActionMap map= new ActionMapUIResource();
map.put("doClick", new ClickAction());
return map;
}
/** Creates an input map for associated menu items */
InputMap createMyInputMap(int condition)
{
if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW)
{
return new ComponentInputMapUIResource(menuItem);
}
return null;
}
/** Updates the accelerator bindings for the associated menu item
* (in the case that they have changed).
*/
void updateMyAcceleratorBinding()
{
KeyStroke accelerator= menuItem.getAccelerator();
if (windowInputMap != null)
{
windowInputMap.clear();
}
if (accelerator != null)
{
if (windowInputMap == null)
{
windowInputMap= createMyInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
SwingUtilities.replaceUIInputMap(
menuItem,
JComponent.WHEN_IN_FOCUSED_WINDOW,
windowInputMap);
}
windowInputMap.put(accelerator, "doClick");
}
}
/** Returns the minimum size of the specified component */
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;
}
/** Returns the preferred size of the specified component */
public Dimension getPreferredSize(JComponent c)
{
return getPreferredMenuItemSize(
c,
checkIcon,
arrowIcon,
defaultTextIconGap);
}
/** Returns the maximum size of the specified component */
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;
}
/** Reset static rectangles for positioning of the contained elements */
private void resetRects()
{
iconRect.setBounds(zeroRect);
textRect.setBounds(zeroRect);
acceleratorRect.setBounds(zeroRect);
checkIconRect.setBounds(zeroRect);
arrowIconRect.setBounds(zeroRect);
viewRect.setBounds(0, 0, Short.MAX_VALUE, Short.MAX_VALUE);
r.setBounds(zeroRect);
}
/** Returns the preferred menu item size
*
* @param c The component for which to return the preferred size
* @param checkIcon The check icon (if any)
* @param arrowIcon The arrow icon (if any)
* @param defaultTextIconGap The default gap in pixels between icon and text
*/
protected Dimension getPreferredMenuItemSize(JComponent c, Icon checkIcon, Icon arrowIcon, int defaultTextIconGap)
{
JMenuItem b=(JMenuItem)c;
int w=0;
int h=0;
Icon icon= (Icon) b.getIcon();
String text= b.getText();
KeyStroke accelerator= b.getAccelerator();
String acceleratorText= "";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -