⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 officexpmenuitemui.java

📁 JAVA swing 的office xp 和 office2003 风格。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* ====================================================================
 * 
 * Office Look and Feels License
 * http://sourceforge.net/projects/officelnfs
 *
 * Copyright (c) 2003-2005 Robert Futrell.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The names "Office Look And Feels" and "OfficeLnFs" must not
 *    be used to endorse or promote products derived from this software
 *    without prior written permission. For written permission, please
 *    contact robert_futrell@users.sourceforge.net.
 *
 * 4. Products derived from this software may not be called "OfficeLnFs"
 *    nor may "OfficeLnFs" appear in their names without prior written
 *    permission.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 */ 
package org.fife.plaf.OfficeXP;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import javax.swing.ButtonModel;
import javax.swing.*;
import javax.swing.event.MouseInputListener;
import javax.swing.plaf.ComponentUI;

import com.sun.java.swing.plaf.windows.WindowsMenuItemUI;


/**
 * UI for menu items using the OfficeXP Look and Feel.
 *
 * @author Robert Futrell
 * @version 1.0
 */
public class OfficeXPMenuItemUI extends WindowsMenuItemUI {

	static final int MENU_ITEM_HEIGHT	= 23;

	static final String MAX_TEXT_WIDTH =  "maxTextWidth";
	static final String MAX_ACC_WIDTH  =  "maxAccWidth";

	// These rects are used for painting and preferredsize calculations.
	// They used to be regenerated constantly.  Now they are reused.
	protected static final Rectangle zeroRect = new Rectangle(0,0,0,0);
	protected static Rectangle iconRect = new Rectangle();
	protected static Rectangle textRect = new Rectangle();
	protected static Rectangle acceleratorRect = new Rectangle();
	protected static Rectangle viewRect = new Rectangle(Short.MAX_VALUE, Short.MAX_VALUE);
	protected static Rectangle r = new Rectangle();


	protected MouseInputListener createMouseInputListener(JComponent c) {
		return new RMouseInputHandler();
	}


    public static ComponentUI createUI(JComponent c) {
        return new OfficeXPMenuItemUI();
    }


    protected Dimension getPreferredMenuItemSize(JComponent c,
                                                     Icon checkIcon,
                                                     Icon arrowIcon,
                                                     int defaultTextIconGap) {
		JMenuItem b = (JMenuItem) c;
		Icon icon = (Icon) b.getIcon();
		String text = b.getText();
		KeyStroke accelerator =  b.getAccelerator();
		String acceleratorText = "";

		if (accelerator != null) {
			int modifiers = accelerator.getModifiers();
			if (modifiers > 0) {
				acceleratorText = KeyEvent.getKeyModifiersText(modifiers);
				acceleratorText += "+";
			}
			int keyCode = accelerator.getKeyCode();
			if (keyCode != 0) {
				acceleratorText += KeyEvent.getKeyText(keyCode);
			}
			else {
				acceleratorText += accelerator.getKeyChar();
			}
		}

		Font font = b.getFont();
		FontMetrics fm = c.getFontMetrics(font);

		resetRects();

		layoutMenuItem(
				fm, text, acceleratorText, icon, checkIcon, arrowIcon,
				viewRect, iconRect, textRect, acceleratorRect,
				text == null ? 0 : defaultTextIconGap,
				defaultTextIconGap
				);

		// Find the union of the icon and text rects.
		r.setBounds(textRect);
		r = SwingUtilities.computeUnion(iconRect.x, iconRect.y,
								iconRect.width, iconRect.height, r);

		// To make the text and accelerators of each menu item in a menu
		// align, we'll check the width of each for this menu item, and if
		// either value is greater than the parent menu's cached current
		// greatest value, it is updated.  Since all menu items do this
		// (even child JMenus, but they do it in OfficeXPMenuUI), the
		// parent menu will have the proper values.

		// We need a JComponent-derived parent in order to store the
		// width properties.
		Container parent = menuItem.getParent();
		if (parent != null && parent instanceof JComponent) {

			JComponent p = (JComponent) parent;

			// Get widest values so far from parent, or null if none yet.
			Integer maxTextWidth = (Integer) p.getClientProperty(MAX_TEXT_WIDTH);
			Integer maxAccWidth = (Integer) p.getClientProperty(MAX_ACC_WIDTH);
			int maxTextValue = maxTextWidth!=null ? maxTextWidth.intValue() : 0;
			int maxAccValue = maxAccWidth!=null ? maxAccWidth.intValue() : 0;

			//Compare the text widths, and adjust the r.width to the widest.
			if (r.width < maxTextValue) {
				r.width = maxTextValue;
			}
			else {
				p.putClientProperty(MAX_TEXT_WIDTH, new Integer(r.width) );
			}

			// Compare the accelarator widths.
			if (acceleratorRect.width > maxAccValue) {
				maxAccValue = acceleratorRect.width;
				p.putClientProperty(MAX_ACC_WIDTH, new Integer(acceleratorRect.width) );
			}

			// Add on the widest accelerator.
			r.width += maxAccValue;
			r.width += defaultTextIconGap;

		}

		// Add in the checkIcon
		r.width += 20;//checkIconRect.width;
		r.width += defaultTextIconGap;

		// Add in the arrowIcon
		r.width += defaultTextIconGap;
		r.width += 12;//arrowIconRect.width;

		// Add in the "padding" on either side of the menu item.
		r.width += 2*defaultTextIconGap;

		Insets insets = b.getInsets();
		if(insets != null) {
			r.width += insets.left + insets.right;
			r.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(r.width%2 == 0) {
			r.width++;
		}

		// if the height is even, bump it up one. This is critical
		// for the text to center properly
		if(r.height%2 == 0) {
			r.height++;
		}

		return new Dimension((int)r.getWidth(), MENU_ITEM_HEIGHT);

	}


   /**
     * Compute and return the location of the icons origin, the
     * location of origin of the text baseline, and a possibly clipped
     * version of the compound labels string.  Locations are computed
     * relative to the viewR rectangle.
     */
    public static String layoutCompoundLabel(JComponent c, FontMetrics fm,
    									String text, Rectangle viewR,
    									Rectangle iconR, Rectangle textR) {

		boolean ltr = true;
		if (c!=null) ltr = c.getComponentOrientation().isLeftToRight();
		//int hAlign = ltr ? SwingConstants.RIGHT : SwingConstants.LEFT;
		int hTextPos = ltr ? SwingConstants.LEFT : SwingConstants.RIGHT;

		// Note that iconR won't matter if an icon doesn't exist, so it
		// doesn't matter that it's in the same (x,y) location as the text.
		iconR.width  = 20;
		iconR.height = 20;
		if (hTextPos==SwingConstants.LEFT) {
			iconR.x = 4;
		}
		else {
			iconR.x = viewR.x+viewR.width-20-1;
		}
		iconR.y = viewR.y + (viewR.height/2) - 7; //(iconR.height/2);

		// Initialize the text bounds rectangle textR.  If a null
		// or and empty String was specified we substitute "" here
		// and use 0,0,0,0 for textR.
		boolean textIsEmpty = (text == null) || text.equals("");
		if (textIsEmpty) {
			textR.width = textR.height = 0;
			text = "";
		}
		else {

			textR.width = SwingUtilities.computeStringWidth(fm,text);
			textR.height = fm.getHeight();

            /* If the label text string is too wide to fit within the available
             * space, "..." and as many characters as will fit will be
             * displayed instead.
             */
            int availTextWidth = viewR.width - 32;

            if (textR.width > availTextWidth) {
			    String clipString = "...";
			    int totalWidth = SwingUtilities.computeStringWidth(fm,clipString);
			    int nChars;
			    for(nChars = 0; nChars < text.length(); nChars++) {
					totalWidth += fm.charWidth(text.charAt(nChars));
					if (totalWidth > availTextWidth)
					    break;
			    }
			    text = text.substring(0, nChars) + clipString;
			    textR.width = SwingUtilities.computeStringWidth(fm,text);
            }

		}

		// If this is a top-level menu, there will be no icon.
		if ((c instanceof JMenu) && ((JMenu)c).isTopLevelMenu()) {
			int nonShadowWidth = viewR.width - 4;
			textR.x = viewR.x + nonShadowWidth/2 - textR.width/2;	// Text will be centered.
		}
		else
			// Text will be placed after the icon/check/whatever if it's not
			// a top-level menu item.
			if (hTextPos==SwingConstants.LEFT) {
				textR.x = 32;
			}
			else { // SwingConstants.RIGHT
				Integer i = (Integer)c.getClientProperty(MAX_ACC_WIDTH);
				//int maxAccWidth = i==null ? 0 : i.intValue();
				textR.x = viewR.x+viewR.width -(32 + /*defaultTextIconGap*/5 + textR.width);
			}

		// Must compute text's y-coordinate after textR.height has been computed.
		textR.y = viewR.y + (viewR.height/2) - (textR.height/2);

        return text;

    }


	/**
	 * Compute and return the location of the icons origin, the
	 * location of origin of the text baseline, and a possibly clipped
	 * version of the compound labels string.  Locations are computed
	 * relative to the viewRect rectangle.
	 */
	protected String layoutMenuItem(FontMetrics fm, String text,
				String acceleratorText, Icon icon, Icon checkIcon,
				Icon arrowIcon, Rectangle viewRect, Rectangle iconRect,
				Rectangle textRect, Rectangle acceleratorRect,
				int textIconGap, int menuItemGap) {

		// Lay out the text and icon rectangles.
		layoutCompoundLabel(menuItem, fm, text, viewRect, iconRect, textRect);

		// Give dimensions to the accelerator text rectangle if the text is
		// actually something.
		if (!acceleratorText.equals("")) {
			acceleratorRect.width = SwingUtilities.computeStringWidth( fm, acceleratorText );
			acceleratorRect.height = fm.getHeight();
			if (menuItem.getComponentOrientation().isLeftToRight()) {
				acceleratorRect.x = viewRect.x + viewRect.width - 12/*arrowIconRect.width*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -