/** Copyright (c) 2002, 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 sun.swing;import static sun.swing.SwingUtilities2.BASICMENUITEMUI_MAX_TEXT_OFFSET;import javax.swing.*;import javax.swing.plaf.basic.BasicHTML;import javax.swing.text.View;import java.awt.*;import java.awt.event.KeyEvent;import java.util.Map;import java.util.HashMap;/*** Calculates preferred size and layouts menu items.*/public class MenuItemLayoutHelper {/* Client Property keys for calculation of maximal widths */public static final StringUIClientPropertyKey MAX_ARROW_WIDTH =new StringUIClientPropertyKey("maxArrowWidth");public static final StringUIClientPropertyKey MAX_CHECK_WIDTH =new StringUIClientPropertyKey("maxCheckWidth");public static final StringUIClientPropertyKey MAX_ICON_WIDTH =new StringUIClientPropertyKey("maxIconWidth");public static final StringUIClientPropertyKey MAX_TEXT_WIDTH =new StringUIClientPropertyKey("maxTextWidth");public static final StringUIClientPropertyKey MAX_ACC_WIDTH =new StringUIClientPropertyKey("maxAccWidth");public static final StringUIClientPropertyKey MAX_LABEL_WIDTH =new StringUIClientPropertyKey("maxLabelWidth");private JMenuItem mi;private JComponent miParent;private Font font;private Font accFont;private FontMetrics fm;private FontMetrics accFm;private Icon icon;private Icon checkIcon;private Icon arrowIcon;private String text;private String accText;private boolean isColumnLayout;private boolean useCheckAndArrow;private boolean isLeftToRight;private boolean isTopLevelMenu;private View htmlView;private int verticalAlignment;private int horizontalAlignment;private int verticalTextPosition;private int horizontalTextPosition;private int gap;private int leadingGap;private int afterCheckIconGap;private int minTextOffset;private int leftTextExtraWidth;private Rectangle viewRect;private RectSize iconSize;private RectSize textSize;private RectSize accSize;private RectSize checkSize;private RectSize arrowSize;private RectSize labelSize;/*** The empty protected constructor is necessary for derived classes.*/protected MenuItemLayoutHelper() {}public MenuItemLayoutHelper(JMenuItem mi, Icon checkIcon, Icon arrowIcon,Rectangle viewRect, int gap, String accDelimiter,boolean isLeftToRight, Font font, Font accFont,boolean useCheckAndArrow, String propertyPrefix) {reset(mi, checkIcon, arrowIcon, viewRect, gap, accDelimiter,isLeftToRight, font, accFont, useCheckAndArrow, propertyPrefix);}protected void reset(JMenuItem mi, Icon checkIcon, Icon arrowIcon,Rectangle viewRect, int gap, String accDelimiter,boolean isLeftToRight, Font font, Font accFont,boolean useCheckAndArrow, String propertyPrefix) {this.mi = mi;this.miParent = getMenuItemParent(mi);this.accText = getAccText(accDelimiter);this.verticalAlignment = mi.getVerticalAlignment();this.horizontalAlignment = mi.getHorizontalAlignment();this.verticalTextPosition = mi.getVerticalTextPosition();this.horizontalTextPosition = mi.getHorizontalTextPosition();this.useCheckAndArrow = useCheckAndArrow;this.font = font;this.accFont = accFont;this.fm = mi.getFontMetrics(font);this.accFm = mi.getFontMetrics(accFont);this.isLeftToRight = isLeftToRight;this.isColumnLayout = isColumnLayout(isLeftToRight,horizontalAlignment, horizontalTextPosition,verticalTextPosition);this.isTopLevelMenu = (this.miParent == null) ? true : false;this.checkIcon = checkIcon;this.icon = getIcon(propertyPrefix);this.arrowIcon = arrowIcon;this.text = mi.getText();this.gap = gap;this.afterCheckIconGap = getAfterCheckIconGap(propertyPrefix);this.minTextOffset = getMinTextOffset(propertyPrefix);this.htmlView = (View) mi.getClientProperty(BasicHTML.propertyKey);this.viewRect = viewRect;this.iconSize = new RectSize();this.textSize = new RectSize();this.accSize = new RectSize();this.checkSize = new RectSize();this.arrowSize = new RectSize();this.labelSize = new RectSize();calcExtraWidths();calcWidthsAndHeights();setOriginalWidths();calcMaxWidths();this.leadingGap = getLeadingGap(propertyPrefix);calcMaxTextOffset(viewRect);}private void calcExtraWidths() {leftTextExtraWidth = getLeftExtraWidth(text);}private int getLeftExtraWidth(String str) {int lsb = SwingUtilities2.getLeftSideBearing(mi, fm, str);if (lsb < 0) {return -lsb;} else {return 0;}}private void setOriginalWidths() {iconSize.origWidth = iconSize.width;textSize.origWidth = textSize.width;accSize.origWidth = accSize.width;checkSize.origWidth = checkSize.width;arrowSize.origWidth = arrowSize.width;}@SuppressWarnings("deprecation")private String getAccText(String acceleratorDelimiter) {String accText = "";KeyStroke accelerator = mi.getAccelerator();if (accelerator != null) {int modifiers = accelerator.getModifiers();if (modifiers > 0) {accText = KeyEvent.getKeyModifiersText(modifiers);accText += acceleratorDelimiter;}int keyCode = accelerator.getKeyCode();if (keyCode != 0) {accText += KeyEvent.getKeyText(keyCode);} else {accText += accelerator.getKeyChar();}}return accText;}private Icon getIcon(String propertyPrefix) {// 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.Icon icon = null;MenuItemCheckIconFactory iconFactory =(MenuItemCheckIconFactory) UIManager.get(propertyPrefix+ ".checkIconFactory");if (!isColumnLayout || !useCheckAndArrow || iconFactory == null|| !iconFactory.isCompatible(checkIcon, propertyPrefix)) {icon = mi.getIcon();}return icon;}private int getMinTextOffset(String propertyPrefix) {int minimumTextOffset = 0;Object minimumTextOffsetObject =UIManager.get(propertyPrefix + ".minimumTextOffset");if (minimumTextOffsetObject instanceof Integer) {minimumTextOffset = (Integer) minimumTextOffsetObject;}return minimumTextOffset;}private int getAfterCheckIconGap(String propertyPrefix) {int afterCheckIconGap = gap;Object afterCheckIconGapObject =UIManager.get(propertyPrefix + ".afterCheckIconGap");if (afterCheckIconGapObject instanceof Integer) {afterCheckIconGap = (Integer) afterCheckIconGapObject;}return afterCheckIconGap;}private int getLeadingGap(String propertyPrefix) {if (checkSize.getMaxWidth() > 0) {return getCheckOffset(propertyPrefix);} else {return gap; // There is no any check icon}}private int getCheckOffset(String propertyPrefix) {int checkIconOffset = gap;Object checkIconOffsetObject =UIManager.get(propertyPrefix + ".checkIconOffset");if (checkIconOffsetObject instanceof Integer) {checkIconOffset = (Integer) checkIconOffsetObject;}return checkIconOffset;}protected void calcWidthsAndHeights() {// iconRectif (icon != null) {iconSize.width = icon.getIconWidth();iconSize.height = icon.getIconHeight();}// accRectif (!accText.equals("")) {accSize.width = SwingUtilities2.stringWidth(mi, accFm, accText);accSize.height = accFm.getHeight();}// textRectif (text == null) {text = "";} else if (!text.equals("")) {if (htmlView != null) {// Text is HTMLtextSize.width =(int) htmlView.getPreferredSpan(View.X_AXIS);textSize.height =(int) htmlView.getPreferredSpan(View.Y_AXIS);} else {// Text isn't HTMLtextSize.width = SwingUtilities2.stringWidth(mi, fm, text);textSize.height = fm.getHeight();}}if (useCheckAndArrow) {// checkIconif (checkIcon != null) {checkSize.width = checkIcon.getIconWidth();checkSize.height = checkIcon.getIconHeight();}// arrowRectif (arrowIcon != null) {arrowSize.width = arrowIcon.getIconWidth();arrowSize.height = arrowIcon.getIconHeight();}}// labelRectif (isColumnLayout) {labelSize.width = iconSize.width + textSize.width + gap;labelSize.height = max(checkSize.height, iconSize.height,textSize.height, accSize.height, arrowSize.height);} else {Rectangle textRect = new Rectangle();Rectangle iconRect = new Rectangle();SwingUtilities.layoutCompoundLabel(mi, fm, text, icon,verticalAlignment, horizontalAlignment,verticalTextPosition, horizontalTextPosition,viewRect, iconRect, textRect, gap);textRect.width += leftTextExtraWidth;Rectangle labelRect = iconRect.union(textRect);labelSize.height = labelRect.height;labelSize.width = labelRect.width;}}protected void calcMaxWidths() {calcMaxWidth(checkSize, MAX_CHECK_WIDTH);calcMaxWidth(arrowSize, MAX_ARROW_WIDTH);calcMaxWidth(accSize, MAX_ACC_WIDTH);if (isColumnLayout) {calcMaxWidth(iconSize, MAX_ICON_WIDTH);calcMaxWidth(textSize, MAX_TEXT_WIDTH);int curGap = gap;if ((iconSize.getMaxWidth() == 0)|| (textSize.getMaxWidth() == 0)) {curGap = 0;}labelSize.maxWidth =calcMaxValue(MAX_LABEL_WIDTH, iconSize.maxWidth+ textSize.maxWidth + curGap);} else {// We shouldn't use current icon and text widths// in maximal widths calculation for complex layout.iconSize.maxWidth = getParentIntProperty(MAX_ICON_WIDTH);calcMaxWidth(labelSize, MAX_LABEL_WIDTH);// If maxLabelWidth is wider// than the widest icon + the widest text + gap,// we should update the maximal text witdhint candidateTextWidth = labelSize.maxWidth - iconSize.maxWidth;if (iconSize.maxWidth > 0) {candidateTextWidth -= gap;}textSize.maxWidth = calcMaxValue(MAX_TEXT_WIDTH, candidateTextWidth);}}protected void calcMaxWidth(RectSize rs, Object key) {rs.maxWidth = calcMaxValue(key, rs.width);}/*** Calculates and returns maximal value through specified parent component* client property.** @param propertyName name of the property, which stores the maximal value.* @param value a value which pretends to be maximal* @return maximal value among the parent property and the value.*/protected int calcMaxValue(Object propertyName, int value) {// Get maximal value from parent client propertyint maxValue = getParentIntProperty(propertyName);// Store new maximal width in parent client propertyif (value > maxValue) {if (miParent != null) {miParent.putClientProperty(propertyName, value);}return value;} else {return maxValue;}}/*** Returns parent client property as int.* @param propertyName name of the parent property.* @return value of the property as int.*/protected int getParentIntProperty(Object propertyName) {Object value = null;if (miParent != null) {value = miParent.getClientProperty(propertyName);}if ((value == null) || !(value instanceof Integer)) {value = 0;}return (Integer) value;}public static boolean isColumnLayout(boolean isLeftToRight,JMenuItem mi) {assert(mi != null);return isColumnLayout(isLeftToRight, mi.getHorizontalAlignment(),mi.getHorizontalTextPosition(), mi.getVerticalTextPosition());}/*** Answers should we do column layout for a menu item or not.* We do it when a user doesn't set any alignments* and text positions manually, except the vertical alignment.*/public static boolean isColumnLayout(boolean isLeftToRight,int horizontalAlignment,int horizontalTextPosition,int verticalTextPosition) {if (verticalTextPosition != SwingConstants.CENTER) {return false;}if (isLeftToRight) {if (horizontalAlignment != SwingConstants.LEADING&& horizontalAlignment != SwingConstants.LEFT) {return false;}if (horizontalTextPosition != SwingConstants.TRAILING&& horizontalTextPosition != SwingConstants.RIGHT) {return false;}} else {if (horizontalAlignment != SwingConstants.LEADING&& horizontalAlignment != SwingConstants.RIGHT) {return false;}if (horizontalTextPosition != SwingConstants.TRAILING&& horizontalTextPosition != SwingConstants.LEFT) {return false;}}return true;}/*** Calculates maximal text offset.* It is required for some L&Fs (ex: Vista L&F).* The offset is meaningful only for L2R column layout.** @param viewRect the rectangle, the maximal text offset* will be calculated for.*/private void calcMaxTextOffset(Rectangle viewRect) {if (!isColumnLayout || !isLeftToRight) {return;}// Calculate the current text offsetint offset = viewRect.x + leadingGap + checkSize.maxWidth+ afterCheckIconGap + iconSize.maxWidth + gap;if (checkSize.maxWidth == 0) {offset -= afterCheckIconGap;}if (iconSize.maxWidth == 0) {offset -= gap;}// maximal text offset shouldn't be less than minimal text offset;if (offset < minTextOffset) {offset = minTextOffset;}// Calculate and store the maximal text offsetcalcMaxValue(SwingUtilities2.BASICMENUITEMUI_MAX_TEXT_OFFSET, offset);}/*** Layout icon, text, check icon, accelerator text and arrow icon* in the viewRect and return their positions.** If horizontalAlignment, verticalTextPosition and horizontalTextPosition* are default (user doesn't set any manually) the layouting algorithm is:* Elements are layouted in the five columns:* check icon + icon + text + accelerator text + arrow icon** In the other case elements are layouted in the four columns:* check icon + label + accelerator text + arrow icon* Label is union of icon and text.** The order of columns can be reversed.* It depends on the menu item orientation.*/public LayoutResult layoutMenuItem() {LayoutResult lr = createLayoutResult();prepareForLayout(lr);if (isColumnLayout()) {if (isLeftToRight()) {doLTRColumnLayout(lr, getLTRColumnAlignment());} else {doRTLColumnLayout(lr, getRTLColumnAlignment());}} else {if (isLeftToRight()) {doLTRComplexLayout(lr, getLTRColumnAlignment());} else {doRTLComplexLayout(lr, getRTLColumnAlignment());}}alignAccCheckAndArrowVertically(lr);return lr;}private LayoutResult createLayoutResult() {return new LayoutResult(new Rectangle(iconSize.width, iconSize.height),new Rectangle(textSize.width, textSize.height),new Rectangle(accSize.width, accSize.height),new Rectangle(checkSize.width, checkSize.height),new Rectangle(arrowSize.width, arrowSize.height),new Rectangle(labelSize.width, labelSize.height));}public ColumnAlignment getLTRColumnAlignment() {return ColumnAlignment.LEFT_ALIGNMENT;}public ColumnAlignment getRTLColumnAlignment() {return ColumnAlignment.RIGHT_ALIGNMENT;}protected void prepareForLayout(LayoutResult lr) {lr.checkRect.width = checkSize.maxWidth;lr.accRect.width = accSize.maxWidth;lr.arrowRect.width = arrowSize.maxWidth;}/*** Aligns the accelertor text and the check and arrow icons vertically* with the center of the label rect.*/private void alignAccCheckAndArrowVertically(LayoutResult lr) {lr.accRect.y = (int)(lr.labelRect.y+ (float)lr.labelRect.height/2- (float)lr.accRect.height/2);fixVerticalAlignment(lr, lr.accRect);if (useCheckAndArrow) {lr.arrowRect.y = (int)(lr.labelRect.y+ (float)lr.labelRect.height/2- (float)lr.arrowRect.height/2);lr.checkRect.y = (int)(lr.labelRect.y+ (float)lr.labelRect.height/2- (float)lr.checkRect.height/2);fixVerticalAlignment(lr, lr.arrowRect);fixVerticalAlignment(lr, lr.checkRect);}}/*** Fixes vertical alignment of all menu item elements if rect.y* or (rect.y + rect.height) is out of viewRect bounds*/private void fixVerticalAlignment(LayoutResult lr, Rectangle r) {int delta = 0;if (r.y < viewRect.y) {delta = viewRect.y - r.y;} else if (r.y + r.height > viewRect.y + viewRect.height) {delta = viewRect.y + viewRect.height - r.y - r.height;}if (delta != 0) {lr.checkRect.y += delta;lr.iconRect.y += delta;lr.textRect.y += delta;lr.accRect.y += delta;lr.arrowRect.y += delta;lr.labelRect.y += delta;}}private void doLTRColumnLayout(LayoutResult lr, ColumnAlignment alignment) {// Set maximal width for all the five basic rects// (three other ones are already maximal)lr.iconRect.width = iconSize.maxWidth;lr.textRect.width = textSize.maxWidth;// Set X coordinates// All rects will be aligned at the left sidecalcXPositionsLTR(viewRect.x, leadingGap, gap, lr.checkRect,lr.iconRect, lr.textRect);// Tune afterCheckIconGapif (lr.checkRect.width > 0) { // there is the afterCheckIconGaplr.iconRect.x += afterCheckIconGap - gap;lr.textRect.x += afterCheckIconGap - gap;}calcXPositionsRTL(viewRect.x + viewRect.width, leadingGap, gap,lr.arrowRect, lr.accRect);// Take into account minimal text offsetint textOffset = lr.textRect.x - viewRect.x;if (!isTopLevelMenu && (textOffset < minTextOffset)) {lr.textRect.x += minTextOffset - textOffset;}alignRects(lr, alignment);// Set Y coordinate for text and icon.// Y coordinates for other rects// will be calculated later in layoutMenuItem.calcTextAndIconYPositions(lr);// Calculate valid X and Y coordinates for labelRectlr.setLabelRect(lr.textRect.union(lr.iconRect));}private void doLTRComplexLayout(LayoutResult lr, ColumnAlignment alignment) {lr.labelRect.width = labelSize.maxWidth;// Set X coordinatescalcXPositionsLTR(viewRect.x, leadingGap, gap, lr.checkRect,lr.labelRect);// Tune afterCheckIconGapif (lr.checkRect.width > 0) { // there is the afterCheckIconGaplr.labelRect.x += afterCheckIconGap - gap;}calcXPositionsRTL(viewRect.x + viewRect.width,leadingGap, gap, lr.arrowRect, lr.accRect);// Take into account minimal text offsetint labelOffset = lr.labelRect.x - viewRect.x;if (!isTopLevelMenu && (labelOffset < minTextOffset)) {lr.labelRect.x += minTextOffset - labelOffset;}alignRects(lr, alignment);// Center labelRect verticallycalcLabelYPosition(lr);layoutIconAndTextInLabelRect(lr);}private void doRTLColumnLayout(LayoutResult lr, ColumnAlignment alignment) {// Set maximal width for all the five basic rects// (three other ones are already maximal)lr.iconRect.width = iconSize.maxWidth;lr.textRect.width = textSize.maxWidth;// Set X coordinatescalcXPositionsRTL(viewRect.x + viewRect.width, leadingGap, gap,lr.checkRect, lr.iconRect, lr.textRect);// Tune the gap after check iconif (lr.checkRect.width > 0) { // there is the gap after check iconlr.iconRect.x -= afterCheckIconGap - gap;lr.textRect.x -= afterCheckIconGap - gap;}calcXPositionsLTR(viewRect.x, leadingGap, gap, lr.arrowRect,lr.accRect);// Take into account minimal text offsetint textOffset = (viewRect.x + viewRect.width)- (lr.textRect.x + lr.textRect.width);if (!isTopLevelMenu && (textOffset < minTextOffset)) {lr.textRect.x -= minTextOffset - textOffset;}alignRects(lr, alignment);// Set Y coordinates for text and icon.// Y coordinates for other rects// will be calculated later in layoutMenuItem.calcTextAndIconYPositions(lr);// Calculate valid X and Y coordinate for labelRectlr.setLabelRect(lr.textRect.union(lr.iconRect));}private void doRTLComplexLayout(LayoutResult lr, ColumnAlignment alignment) {lr.labelRect.width = labelSize.maxWidth;// Set X coordinatescalcXPositionsRTL(viewRect.x + viewRect.width, leadingGap, gap,lr.checkRect, lr.labelRect);// Tune the gap after check iconif (lr.checkRect.width > 0) { // there is the gap after check iconlr.labelRect.x -= afterCheckIconGap - gap;}calcXPositionsLTR(viewRect.x, leadingGap, gap, lr.arrowRect, lr.accRect);// Take into account minimal text offsetint labelOffset = (viewRect.x + viewRect.width)- (lr.labelRect.x + lr.labelRect.width);if (!isTopLevelMenu && (labelOffset < minTextOffset)) {lr.labelRect.x -= minTextOffset - labelOffset;}alignRects(lr, alignment);// Center labelRect verticallycalcLabelYPosition(lr);layoutIconAndTextInLabelRect(lr);}private void alignRects(LayoutResult lr, ColumnAlignment alignment) {alignRect(lr.checkRect, alignment.getCheckAlignment(),checkSize.getOrigWidth());alignRect(lr.iconRect, alignment.getIconAlignment(),iconSize.getOrigWidth());alignRect(lr.textRect, alignment.getTextAlignment(),textSize.getOrigWidth());alignRect(lr.accRect, alignment.getAccAlignment(),accSize.getOrigWidth());alignRect(lr.arrowRect, alignment.getArrowAlignment(),arrowSize.getOrigWidth());}private void alignRect(Rectangle rect, int alignment, int origWidth) {if (alignment == SwingConstants.RIGHT) {rect.x = rect.x + rect.width - origWidth;}rect.width = origWidth;}protected void layoutIconAndTextInLabelRect(LayoutResult lr) {lr.setTextRect(new Rectangle());lr.setIconRect(new Rectangle());SwingUtilities.layoutCompoundLabel(mi, fm, text,icon, verticalAlignment, horizontalAlignment,verticalTextPosition, horizontalTextPosition, lr.labelRect,lr.iconRect, lr.textRect, gap);}private void calcXPositionsLTR(int startXPos, int leadingGap,int gap, Rectangle... rects) {int curXPos = startXPos + leadingGap;for (Rectangle rect : rects) {rect.x = curXPos;if (rect.width > 0) {curXPos += rect.width + gap;}}}private void calcXPositionsRTL(int startXPos, int leadingGap,int gap, Rectangle... rects) {int curXPos = startXPos - leadingGap;for (Rectangle rect : rects) {rect.x = curXPos - rect.width;if (rect.width > 0) {curXPos -= rect.width + gap;}}}/*** Sets Y coordinates of text and icon* taking into account the vertical alignment*/private void calcTextAndIconYPositions(LayoutResult lr) {if (verticalAlignment == SwingUtilities.TOP) {lr.textRect.y = (int)(viewRect.y+ (float)lr.labelRect.height/2- (float)lr.textRect.height/2);lr.iconRect.y = (int)(viewRect.y+ (float)lr.labelRect.height/2- (float)lr.iconRect.height/2);} else if (verticalAlignment == SwingUtilities.CENTER) {lr.textRect.y = (int)(viewRect.y+ (float)viewRect.height/2- (float)lr.textRect.height/2);lr.iconRect.y = (int)(viewRect.y+ (float)viewRect.height/2- (float)lr.iconRect.height/2);}else if (verticalAlignment == SwingUtilities.BOTTOM) {lr.textRect.y = (int)(viewRect.y+ viewRect.height- (float)lr.labelRect.height/2- (float)lr.textRect.height/2);lr.iconRect.y = (int)(viewRect.y+ viewRect.height- (float)lr.labelRect.height/2- (float)lr.iconRect.height/2);}}/*** Sets labelRect Y coordinate* taking into account the vertical alignment*/private void calcLabelYPosition(LayoutResult lr) {if (verticalAlignment == SwingUtilities.TOP) {lr.labelRect.y = viewRect.y;} else if (verticalAlignment == SwingUtilities.CENTER) {lr.labelRect.y = (int)(viewRect.y+ (float)viewRect.height/2- (float)lr.labelRect.height/2);} else if (verticalAlignment == SwingUtilities.BOTTOM) {lr.labelRect.y = viewRect.y + viewRect.height- lr.labelRect.height;}}/*** Returns parent of this component if it is not a top-level menu* Otherwise returns null.* @param menuItem the menu item whose parent will be returned.* @return parent of this component if it is not a top-level menu* Otherwise returns null.*/public static JComponent getMenuItemParent(JMenuItem menuItem) {Container parent = menuItem.getParent();if ((parent instanceof JComponent) &&(!(menuItem instanceof JMenu) ||!((JMenu)menuItem).isTopLevelMenu())) {return (JComponent) parent;} else {return null;}}public static void clearUsedParentClientProperties(JMenuItem menuItem) {clearUsedClientProperties(getMenuItemParent(menuItem));}public static void clearUsedClientProperties(JComponent c) {if (c != null) {c.putClientProperty(MAX_ARROW_WIDTH, null);c.putClientProperty(MAX_CHECK_WIDTH, null);c.putClientProperty(MAX_ACC_WIDTH, null);c.putClientProperty(MAX_TEXT_WIDTH, null);c.putClientProperty(MAX_ICON_WIDTH, null);c.putClientProperty(MAX_LABEL_WIDTH, null);c.putClientProperty(BASICMENUITEMUI_MAX_TEXT_OFFSET, null);}}/*** Finds and returns maximal integer value in the given array.* @param values array where the search will be performed.* @return maximal vaule.*/public static int max(int... values) {int maxValue = Integer.MIN_VALUE;for (int i : values) {if (i > maxValue) {maxValue = i;}}return maxValue;}public static Rectangle createMaxRect() {return new Rectangle(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE);}public static void addMaxWidth(RectSize size, int gap, Dimension result) {if (size.maxWidth > 0) {result.width += size.maxWidth + gap;}}public static void addWidth(int width, int gap, Dimension result) {if (width > 0) {result.width += width + gap;}}public JMenuItem getMenuItem() {return mi;}public JComponent getMenuItemParent() {return miParent;}public Font getFont() {return font;}public Font getAccFont() {return accFont;}public FontMetrics getFontMetrics() {return fm;}public FontMetrics getAccFontMetrics() {return accFm;}public Icon getIcon() {return icon;}public Icon getCheckIcon() {return checkIcon;}public Icon getArrowIcon() {return arrowIcon;}public String getText() {return text;}public String getAccText() {return accText;}public boolean isColumnLayout() {return isColumnLayout;}public boolean useCheckAndArrow() {return useCheckAndArrow;}public boolean isLeftToRight() {return isLeftToRight;}public boolean isTopLevelMenu() {return isTopLevelMenu;}public View getHtmlView() {return htmlView;}public int getVerticalAlignment() {return verticalAlignment;}public int getHorizontalAlignment() {return horizontalAlignment;}public int getVerticalTextPosition() {return verticalTextPosition;}public int getHorizontalTextPosition() {return horizontalTextPosition;}public int getGap() {return gap;}public int getLeadingGap() {return leadingGap;}public int getAfterCheckIconGap() {return afterCheckIconGap;}public int getMinTextOffset() {return minTextOffset;}public Rectangle getViewRect() {return viewRect;}public RectSize getIconSize() {return iconSize;}public RectSize getTextSize() {return textSize;}public RectSize getAccSize() {return accSize;}public RectSize getCheckSize() {return checkSize;}public RectSize getArrowSize() {return arrowSize;}public RectSize getLabelSize() {return labelSize;}protected void setMenuItem(JMenuItem mi) {this.mi = mi;}protected void setMenuItemParent(JComponent miParent) {this.miParent = miParent;}protected void setFont(Font font) {this.font = font;}protected void setAccFont(Font accFont) {this.accFont = accFont;}protected void setFontMetrics(FontMetrics fm) {this.fm = fm;}protected void setAccFontMetrics(FontMetrics accFm) {this.accFm = accFm;}protected void setIcon(Icon icon) {this.icon = icon;}protected void setCheckIcon(Icon checkIcon) {this.checkIcon = checkIcon;}protected void setArrowIcon(Icon arrowIcon) {this.arrowIcon = arrowIcon;}protected void setText(String text) {this.text = text;}protected void setAccText(String accText) {this.accText = accText;}protected void setColumnLayout(boolean columnLayout) {isColumnLayout = columnLayout;}protected void setUseCheckAndArrow(boolean useCheckAndArrow) {this.useCheckAndArrow = useCheckAndArrow;}protected void setLeftToRight(boolean leftToRight) {isLeftToRight = leftToRight;}protected void setTopLevelMenu(boolean topLevelMenu) {isTopLevelMenu = topLevelMenu;}protected void setHtmlView(View htmlView) {this.htmlView = htmlView;}protected void setVerticalAlignment(int verticalAlignment) {this.verticalAlignment = verticalAlignment;}protected void setHorizontalAlignment(int horizontalAlignment) {this.horizontalAlignment = horizontalAlignment;}protected void setVerticalTextPosition(int verticalTextPosition) {this.verticalTextPosition = verticalTextPosition;}protected void setHorizontalTextPosition(int horizontalTextPosition) {this.horizontalTextPosition = horizontalTextPosition;}protected void setGap(int gap) {this.gap = gap;}protected void setLeadingGap(int leadingGap) {this.leadingGap = leadingGap;}protected void setAfterCheckIconGap(int afterCheckIconGap) {this.afterCheckIconGap = afterCheckIconGap;}protected void setMinTextOffset(int minTextOffset) {this.minTextOffset = minTextOffset;}protected void setViewRect(Rectangle viewRect) {this.viewRect = viewRect;}protected void setIconSize(RectSize iconSize) {this.iconSize = iconSize;}protected void setTextSize(RectSize textSize) {this.textSize = textSize;}protected void setAccSize(RectSize accSize) {this.accSize = accSize;}protected void setCheckSize(RectSize checkSize) {this.checkSize = checkSize;}protected void setArrowSize(RectSize arrowSize) {this.arrowSize = arrowSize;}protected void setLabelSize(RectSize labelSize) {this.labelSize = labelSize;}public int getLeftTextExtraWidth() {return leftTextExtraWidth;}/*** Returns false if the component is a JMenu and it is a top* level menu (on the menubar).*/public static boolean useCheckAndArrow(JMenuItem menuItem) {boolean b = true;if ((menuItem instanceof JMenu) &&(((JMenu) menuItem).isTopLevelMenu())) {b = false;}return b;}public static class LayoutResult {private Rectangle iconRect;private Rectangle textRect;private Rectangle accRect;private Rectangle checkRect;private Rectangle arrowRect;private Rectangle labelRect;public LayoutResult() {iconRect = new Rectangle();textRect = new Rectangle();accRect = new Rectangle();checkRect = new Rectangle();arrowRect = new Rectangle();labelRect = new Rectangle();}public LayoutResult(Rectangle iconRect, Rectangle textRect,Rectangle accRect, Rectangle checkRect,Rectangle arrowRect, Rectangle labelRect) {this.iconRect = iconRect;this.textRect = textRect;this.accRect = accRect;this.checkRect = checkRect;this.arrowRect = arrowRect;this.labelRect = labelRect;}public Rectangle getIconRect() {return iconRect;}public void setIconRect(Rectangle iconRect) {this.iconRect = iconRect;}public Rectangle getTextRect() {return textRect;}public void setTextRect(Rectangle textRect) {this.textRect = textRect;}public Rectangle getAccRect() {return accRect;}public void setAccRect(Rectangle accRect) {this.accRect = accRect;}public Rectangle getCheckRect() {return checkRect;}public void setCheckRect(Rectangle checkRect) {this.checkRect = checkRect;}public Rectangle getArrowRect() {return arrowRect;}public void setArrowRect(Rectangle arrowRect) {this.arrowRect = arrowRect;}public Rectangle getLabelRect() {return labelRect;}public void setLabelRect(Rectangle labelRect) {this.labelRect = labelRect;}public Map<String, Rectangle> getAllRects() {Map<String, Rectangle> result = new HashMap<String, Rectangle>();result.put("checkRect", checkRect);result.put("iconRect", iconRect);result.put("textRect", textRect);result.put("accRect", accRect);result.put("arrowRect", arrowRect);result.put("labelRect", labelRect);return result;}}public static class ColumnAlignment {private int checkAlignment;private int iconAlignment;private int textAlignment;private int accAlignment;private int arrowAlignment;public static final ColumnAlignment LEFT_ALIGNMENT =new ColumnAlignment(SwingConstants.LEFT,SwingConstants.LEFT,SwingConstants.LEFT,SwingConstants.LEFT,SwingConstants.LEFT);public static final ColumnAlignment RIGHT_ALIGNMENT =new ColumnAlignment(SwingConstants.RIGHT,SwingConstants.RIGHT,SwingConstants.RIGHT,SwingConstants.RIGHT,SwingConstants.RIGHT);public ColumnAlignment(int checkAlignment, int iconAlignment,int textAlignment, int accAlignment,int arrowAlignment) {this.checkAlignment = checkAlignment;this.iconAlignment = iconAlignment;this.textAlignment = textAlignment;this.accAlignment = accAlignment;this.arrowAlignment = arrowAlignment;}public int getCheckAlignment() {return checkAlignment;}public int getIconAlignment() {return iconAlignment;}public int getTextAlignment() {return textAlignment;}public int getAccAlignment() {return accAlignment;}public int getArrowAlignment() {return arrowAlignment;}}public static class RectSize {private int width;private int height;private int origWidth;private int maxWidth;public RectSize() {}public RectSize(int width, int height, int origWidth, int maxWidth) {this.width = width;this.height = height;this.origWidth = origWidth;this.maxWidth = maxWidth;}public int getWidth() {return width;}public int getHeight() {return height;}public int getOrigWidth() {return origWidth;}public int getMaxWidth() {return maxWidth;}public void setWidth(int width) {this.width = width;}public void setHeight(int height) {this.height = height;}public void setOrigWidth(int origWidth) {this.origWidth = origWidth;}public void setMaxWidth(int maxWidth) {this.maxWidth = maxWidth;}public String toString() {return "[w=" + width + ",h=" + height + ",ow="+ origWidth + ",mw=" + maxWidth + "]";}}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。