提交 e9fb2320 编写于 作者: M mlapshin

6584657: GTK Look and Feel: Bugs in menu item layout

Reviewed-by: peterz, alexp
上级 12b796c2
/*
* Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1997-2008 Sun Microsystems, Inc. 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
......@@ -974,6 +974,7 @@ public class SwingUtilities implements SwingConstants
boolean textIsEmpty = (text == null) || text.equals("");
int lsb = 0;
int rsb = 0;
/* Unless both text and icon are non-null, we effectively ignore
* the value of textIconGap.
*/
......@@ -1015,7 +1016,7 @@ public class SwingUtilities implements SwingConstants
if (lsb < 0) {
textR.width -= lsb;
}
int rsb = SwingUtilities2.getRightSideBearing(c, fm, text);
rsb = SwingUtilities2.getRightSideBearing(c, fm, text);
if (rsb > 0) {
textR.width += rsb;
}
......@@ -1118,6 +1119,11 @@ public class SwingUtilities implements SwingConstants
// lsb is negative. Shift the x location so that the text is
// visually drawn at the right location.
textR.x -= lsb;
textR.width += lsb;
}
if (rsb > 0) {
textR.width -= rsb;
}
return text;
......
/*
* Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1998-2008 Sun Microsystems, Inc. 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
......@@ -30,7 +30,6 @@ import javax.swing.plaf.UIResource;
import java.awt.Container;
import java.awt.Dimension;
import static sun.swing.SwingUtilities2.BASICMENUITEMUI_MAX_TEXT_OFFSET;
/**
* The default layout manager for Popup menus and menubars. This
......@@ -49,18 +48,7 @@ public class DefaultMenuLayout extends BoxLayout implements UIResource {
public Dimension preferredLayoutSize(Container target) {
if (target instanceof JPopupMenu) {
JPopupMenu popupMenu = (JPopupMenu) target;
// Before the calculation of menu preferred size
// clear the previously calculated maximal widths and offsets
// in menu's Client Properties
popupMenu.putClientProperty(BasicMenuItemUI.MAX_ACC_WIDTH, null);
popupMenu.putClientProperty(BasicMenuItemUI.MAX_ARROW_WIDTH, null);
popupMenu.putClientProperty(BasicMenuItemUI.MAX_CHECK_WIDTH, null);
popupMenu.putClientProperty(BasicMenuItemUI.MAX_ICON_WIDTH, null);
popupMenu.putClientProperty(BasicMenuItemUI.MAX_LABEL_WIDTH, null);
popupMenu.putClientProperty(BasicMenuItemUI.MAX_TEXT_WIDTH, null);
popupMenu.putClientProperty(BASICMENUITEMUI_MAX_TEXT_OFFSET, null);
sun.swing.MenuItemLayoutHelper.clearUsedClientProperties(popupMenu);
if (popupMenu.getComponentCount() == 0) {
return new Dimension(0, 0);
}
......
/*
* Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2002-2008 Sun Microsystems, Inc. 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
......@@ -47,19 +47,22 @@ class DefaultMenuLayout extends BoxLayout implements UIResource {
super(target, axis);
}
public void invalidateLayout(Container target) {
public Dimension preferredLayoutSize(Container target) {
if (target instanceof JPopupMenu) {
SynthPopupMenuUI popupUI = (SynthPopupMenuUI)((JPopupMenu)target).
getUI();
popupUI.resetAlignmentHints();
JPopupMenu popupMenu = (JPopupMenu) target;
popupMenu.putClientProperty(
SynthMenuItemLayoutHelper.MAX_ACC_OR_ARROW_WIDTH, null);
sun.swing.MenuItemLayoutHelper.clearUsedClientProperties(popupMenu);
if (popupMenu.getComponentCount() == 0) {
return new Dimension(0, 0);
}
}
// Make BoxLayout recalculate cached preferred sizes
super.invalidateLayout(target);
}
public Dimension preferredLayoutSize(Container target) {
if (target instanceof JPopupMenu && target.getComponentCount() == 0) {
return new Dimension(0, 0);
}
return super.preferredLayoutSize(target);
}
}
/*
* Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2002-2008 Sun Microsystems, Inc. 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
......@@ -25,6 +25,8 @@
package javax.swing.plaf.synth;
import sun.swing.SwingUtilities2;
import sun.swing.MenuItemLayoutHelper;
import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.basic.BasicHTML;
......@@ -411,6 +413,198 @@ public class SynthGraphicsUtils {
}
/**
* A quick note about how preferred sizes are calculated... Generally
* speaking, SynthPopupMenuUI will run through the list of its children
* (from top to bottom) and ask each for its preferred size. Each menu
* item will add up the max width of each element (icons, text,
* accelerator spacing, accelerator text or arrow icon) encountered thus
* far, so by the time all menu items have been calculated, we will
* know the maximum (preferred) menu item size for that popup menu.
* Later when it comes time to paint each menu item, we can use those
* same accumulated max element sizes in order to layout the item.
*/
static Dimension getPreferredMenuItemSize(SynthContext context,
SynthContext accContext, JComponent c,
Icon checkIcon, Icon arrowIcon, int defaultTextIconGap,
String acceleratorDelimiter, boolean useCheckAndArrow,
String propertyPrefix) {
JMenuItem mi = (JMenuItem) c;
SynthMenuItemLayoutHelper lh = new SynthMenuItemLayoutHelper(
context, accContext, mi, checkIcon, arrowIcon,
MenuItemLayoutHelper.createMaxRect(), defaultTextIconGap,
acceleratorDelimiter, SynthLookAndFeel.isLeftToRight(mi),
useCheckAndArrow, propertyPrefix);
Dimension result = new Dimension();
// Calculate the result width
int gap = lh.getGap();
result.width = 0;
MenuItemLayoutHelper.addMaxWidth(lh.getCheckSize(), gap, result);
MenuItemLayoutHelper.addMaxWidth(lh.getLabelSize(), gap, result);
MenuItemLayoutHelper.addWidth(lh.getMaxAccOrArrowWidth(), 5 * gap, result);
// The last gap is unnecessary
result.width -= gap;
// 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 lhne 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) {
result.height++;
}
return result;
}
static void applyInsets(Rectangle rect, Insets insets) {
if (insets != null) {
rect.x += insets.left;
rect.y += insets.top;
rect.width -= (insets.right + rect.x);
rect.height -= (insets.bottom + rect.y);
}
}
static void paint(SynthContext context, SynthContext accContext, Graphics g,
Icon checkIcon, Icon arrowIcon, String acceleratorDelimiter,
int defaultTextIconGap, String propertyPrefix) {
JMenuItem mi = (JMenuItem) context.getComponent();
SynthStyle style = context.getStyle();
g.setFont(style.getFont(context));
Rectangle viewRect = new Rectangle(0, 0, mi.getWidth(), mi.getHeight());
applyInsets(viewRect, mi.getInsets());
SynthMenuItemLayoutHelper lh = new SynthMenuItemLayoutHelper(
context, accContext, mi, checkIcon,
arrowIcon, viewRect, defaultTextIconGap, acceleratorDelimiter,
SynthLookAndFeel.isLeftToRight(mi),
MenuItemLayoutHelper.useCheckAndArrow(mi), propertyPrefix);
MenuItemLayoutHelper.LayoutResult lr = lh.layoutMenuItem();
paintMenuItem(g, lh, lr);
}
static void paintMenuItem(Graphics g, SynthMenuItemLayoutHelper lh,
MenuItemLayoutHelper.LayoutResult lr) {
// Save original graphics font and color
Font holdf = g.getFont();
Color holdc = g.getColor();
paintBackground(g, lh);
paintCheckIcon(g, lh, lr);
paintIcon(g, lh, lr);
paintText(g, lh, lr);
paintAccText(g, lh, lr);
paintArrowIcon(g, lh, lr);
// Restore original graphics font and color
g.setColor(holdc);
g.setFont(holdf);
}
static void paintBackground(Graphics g, SynthMenuItemLayoutHelper lh) {
paintBackground(lh.getContext(), g, lh.getMenuItem());
}
static void paintBackground(SynthContext context, Graphics g, JComponent c) {
context.getPainter().paintMenuItemBackground(context, g, 0, 0,
c.getWidth(), c.getHeight());
}
static void paintIcon(Graphics g, SynthMenuItemLayoutHelper lh,
MenuItemLayoutHelper.LayoutResult lr) {
if (lh.getIcon() != null) {
Icon icon;
JMenuItem mi = lh.getMenuItem();
ButtonModel model = mi.getModel();
if (!model.isEnabled()) {
icon = mi.getDisabledIcon();
} else if (model.isPressed() && model.isArmed()) {
icon = mi.getPressedIcon();
if (icon == null) {
// Use default icon
icon = mi.getIcon();
}
} else {
icon = mi.getIcon();
}
if (icon != null) {
Rectangle iconRect = lr.getIconRect();
SynthIcon.paintIcon(icon, lh.getContext(), g, iconRect.x,
iconRect.y, iconRect.width, iconRect.height);
}
}
}
static void paintCheckIcon(Graphics g, SynthMenuItemLayoutHelper lh,
MenuItemLayoutHelper.LayoutResult lr) {
if (lh.getCheckIcon() != null) {
Rectangle checkRect = lr.getCheckRect();
SynthIcon.paintIcon(lh.getCheckIcon(), lh.getContext(), g,
checkRect.x, checkRect.y, checkRect.width, checkRect.height);
}
}
static void paintAccText(Graphics g, SynthMenuItemLayoutHelper lh,
MenuItemLayoutHelper.LayoutResult lr) {
String accText = lh.getAccText();
if (accText != null && !accText.equals("")) {
g.setColor(lh.getAccStyle().getColor(lh.getAccContext(),
ColorType.TEXT_FOREGROUND));
g.setFont(lh.getAccStyle().getFont(lh.getAccContext()));
lh.getAccGraphicsUtils().paintText(lh.getAccContext(), g, accText,
lr.getAccRect().x, lr.getAccRect().y, -1);
}
}
static void paintText(Graphics g, SynthMenuItemLayoutHelper lh,
MenuItemLayoutHelper.LayoutResult lr) {
if (!lh.getText().equals("")) {
if (lh.getHtmlView() != null) {
// Text is HTML
lh.getHtmlView().paint(g, lr.getTextRect());
} else {
// Text isn't HTML
g.setColor(lh.getStyle().getColor(
lh.getContext(), ColorType.TEXT_FOREGROUND));
g.setFont(lh.getStyle().getFont(lh.getContext()));
lh.getGraphicsUtils().paintText(lh.getContext(), g, lh.getText(),
lr.getTextRect().x, lr.getTextRect().y,
lh.getMenuItem().getDisplayedMnemonicIndex());
}
}
}
static void paintArrowIcon(Graphics g, SynthMenuItemLayoutHelper lh,
MenuItemLayoutHelper.LayoutResult lr) {
if (lh.getArrowIcon() != null) {
Rectangle arrowRect = lr.getArrowRect();
SynthIcon.paintIcon(lh.getArrowIcon(), lh.getContext(), g,
arrowRect.x, arrowRect.y, arrowRect.width, arrowRect.height);
}
}
/**
* Wraps a SynthIcon around the Icon interface, forwarding calls to
* the SynthIcon with a given SynthContext.
......
/*
* Copyright 2002-2008 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package javax.swing.plaf.synth;
import sun.swing.StringUIClientPropertyKey;
import sun.swing.MenuItemLayoutHelper;
import sun.swing.plaf.synth.SynthIcon;
import javax.swing.*;
import javax.swing.text.View;
import java.awt.*;
/**
* Calculates preferred size and layouts synth menu items.
*
* All JMenuItems (and JMenus) include enough space for the insets
* plus one or more elements. When we say "label" below, we mean
* "icon and/or text."
*
* Cases to consider for SynthMenuItemUI (visualized here in a
* LTR orientation; the RTL case would be reversed):
* label
* check icon + label
* check icon + label + accelerator
* label + accelerator
*
* Cases to consider for SynthMenuUI (again visualized here in a
* LTR orientation):
* label + arrow
*
* Note that in the above scenarios, accelerator and arrow icon are
* mutually exclusive. This means that if a popup menu contains a mix
* of JMenus and JMenuItems, we only need to allow enough space for
* max(maxAccelerator, maxArrow), and both accelerators and arrow icons
* can occupy the same "column" of space in the menu.
*/
class SynthMenuItemLayoutHelper extends MenuItemLayoutHelper {
public static final StringUIClientPropertyKey MAX_ACC_OR_ARROW_WIDTH =
new StringUIClientPropertyKey("maxAccOrArrowWidth");
public static final ColumnAlignment LTR_ALIGNMENT_1 =
new ColumnAlignment(
SwingConstants.LEFT,
SwingConstants.LEFT,
SwingConstants.LEFT,
SwingConstants.RIGHT,
SwingConstants.RIGHT
);
public static final ColumnAlignment LTR_ALIGNMENT_2 =
new ColumnAlignment(
SwingConstants.LEFT,
SwingConstants.LEFT,
SwingConstants.LEFT,
SwingConstants.LEFT,
SwingConstants.RIGHT
);
public static final ColumnAlignment RTL_ALIGNMENT_1 =
new ColumnAlignment(
SwingConstants.RIGHT,
SwingConstants.RIGHT,
SwingConstants.RIGHT,
SwingConstants.LEFT,
SwingConstants.LEFT
);
public static final ColumnAlignment RTL_ALIGNMENT_2 =
new ColumnAlignment(
SwingConstants.RIGHT,
SwingConstants.RIGHT,
SwingConstants.RIGHT,
SwingConstants.RIGHT,
SwingConstants.LEFT
);
private SynthContext context;
private SynthContext accContext;
private SynthStyle style;
private SynthStyle accStyle;
private SynthGraphicsUtils gu;
private SynthGraphicsUtils accGu;
private boolean alignAcceleratorText;
private int maxAccOrArrowWidth;
public SynthMenuItemLayoutHelper(SynthContext context, SynthContext accContext,
JMenuItem mi, Icon checkIcon, Icon arrowIcon,
Rectangle viewRect, int gap, String accDelimiter,
boolean isLeftToRight, boolean useCheckAndArrow,
String propertyPrefix) {
this.context = context;
this.accContext = accContext;
this.style = context.getStyle();
this.accStyle = accContext.getStyle();
this.gu = style.getGraphicsUtils(context);
this.accGu = accStyle.getGraphicsUtils(accContext);
this.alignAcceleratorText = getAlignAcceleratorText(propertyPrefix);
reset(mi, checkIcon, arrowIcon, viewRect, gap, accDelimiter,
isLeftToRight, style.getFont(context), accStyle.getFont(accContext),
useCheckAndArrow, propertyPrefix);
setLeadingGap(0);
}
private boolean getAlignAcceleratorText(String propertyPrefix) {
return style.getBoolean(context,
propertyPrefix + ".alignAcceleratorText", true);
}
protected void calcWidthsAndHeights() {
// iconRect
if (getIcon() != null) {
getIconSize().setWidth(SynthIcon.getIconWidth(getIcon(), context));
getIconSize().setHeight(SynthIcon.getIconHeight(getIcon(), context));
}
// accRect
if (!getAccText().equals("")) {
getAccSize().setWidth(accGu.computeStringWidth(getAccContext(),
getAccFontMetrics().getFont(), getAccFontMetrics(),
getAccText()));
getAccSize().setHeight(getAccFontMetrics().getHeight());
}
// textRect
if (getText() == null) {
setText("");
} else if (!getText().equals("")) {
if (getHtmlView() != null) {
// Text is HTML
getTextSize().setWidth(
(int) getHtmlView().getPreferredSpan(View.X_AXIS));
getTextSize().setHeight(
(int) getHtmlView().getPreferredSpan(View.Y_AXIS));
} else {
// Text isn't HTML
getTextSize().setWidth(gu.computeStringWidth(context,
getFontMetrics().getFont(), getFontMetrics(),
getText()));
getTextSize().setHeight(getFontMetrics().getHeight());
}
}
if (useCheckAndArrow()) {
// checkIcon
if (getCheckIcon() != null) {
getCheckSize().setWidth(
SynthIcon.getIconWidth(getCheckIcon(), context));
getCheckSize().setHeight(
SynthIcon.getIconHeight(getCheckIcon(), context));
}
// arrowRect
if (getArrowIcon() != null) {
getArrowSize().setWidth(
SynthIcon.getIconWidth(getArrowIcon(), context));
getArrowSize().setHeight(
SynthIcon.getIconHeight(getArrowIcon(), context));
}
}
// labelRect
if (isColumnLayout()) {
getLabelSize().setWidth(getIconSize().getWidth()
+ getTextSize().getWidth() + getGap());
getLabelSize().setHeight(MenuItemLayoutHelper.max(
getCheckSize().getHeight(),
getIconSize().getHeight(),
getTextSize().getHeight(),
getAccSize().getHeight(),
getArrowSize().getHeight()));
} else {
Rectangle textRect = new Rectangle();
Rectangle iconRect = new Rectangle();
gu.layoutText(context, getFontMetrics(), getText(), getIcon(),
getHorizontalAlignment(), getVerticalAlignment(),
getHorizontalTextPosition(), getVerticalTextPosition(),
getViewRect(), iconRect, textRect, getGap());
Rectangle labelRect = iconRect.union(textRect);
getLabelSize().setHeight(labelRect.height);
getLabelSize().setWidth(labelRect.width);
}
}
protected void calcMaxWidths() {
calcMaxWidth(getCheckSize(), MAX_CHECK_WIDTH);
maxAccOrArrowWidth =
calcMaxValue(MAX_ACC_OR_ARROW_WIDTH, getArrowSize().getWidth());
maxAccOrArrowWidth =
calcMaxValue(MAX_ACC_OR_ARROW_WIDTH, getAccSize().getWidth());
if (isColumnLayout()) {
calcMaxWidth(getIconSize(), MAX_ICON_WIDTH);
calcMaxWidth(getTextSize(), MAX_TEXT_WIDTH);
int curGap = getGap();
if ((getIconSize().getMaxWidth() == 0)
|| (getTextSize().getMaxWidth() == 0)) {
curGap = 0;
}
getLabelSize().setMaxWidth(
calcMaxValue(MAX_LABEL_WIDTH, getIconSize().getMaxWidth()
+ getTextSize().getMaxWidth() + curGap));
} else {
// We shouldn't use current icon and text widths
// in maximal widths calculation for complex layout.
getIconSize().setMaxWidth(getParentIntProperty(
MAX_ICON_WIDTH));
calcMaxWidth(getLabelSize(), MAX_LABEL_WIDTH);
// If maxLabelWidth is wider
// than the widest icon + the widest text + gap,
// we should update the maximal text witdh
int candidateTextWidth = getLabelSize().getMaxWidth() -
getIconSize().getMaxWidth();
if (getIconSize().getMaxWidth() > 0) {
candidateTextWidth -= getGap();
}
getTextSize().setMaxWidth(calcMaxValue(
MAX_TEXT_WIDTH, candidateTextWidth));
}
}
public SynthContext getContext() {
return context;
}
public SynthContext getAccContext() {
return accContext;
}
public SynthStyle getStyle() {
return style;
}
public SynthStyle getAccStyle() {
return accStyle;
}
public SynthGraphicsUtils getGraphicsUtils() {
return gu;
}
public SynthGraphicsUtils getAccGraphicsUtils() {
return accGu;
}
public boolean alignAcceleratorText() {
return alignAcceleratorText;
}
public int getMaxAccOrArrowWidth() {
return maxAccOrArrowWidth;
}
protected void prepareForLayout(LayoutResult lr) {
lr.getCheckRect().width = getCheckSize().getMaxWidth();
// An item can have an arrow or a check icon at once
if (useCheckAndArrow() && (!"".equals(getAccText()))) {
lr.getAccRect().width = maxAccOrArrowWidth;
} else {
lr.getArrowRect().width = maxAccOrArrowWidth;
}
}
public ColumnAlignment getLTRColumnAlignment() {
if (alignAcceleratorText()) {
return LTR_ALIGNMENT_2;
} else {
return LTR_ALIGNMENT_1;
}
}
public ColumnAlignment getRTLColumnAlignment() {
if (alignAcceleratorText()) {
return RTL_ALIGNMENT_2;
} else {
return RTL_ALIGNMENT_1;
}
}
protected void layoutIconAndTextInLabelRect(LayoutResult lr) {
lr.setTextRect(new Rectangle());
lr.setIconRect(new Rectangle());
gu.layoutText(context, getFontMetrics(), getText(), getIcon(),
getHorizontalAlignment(), getVerticalAlignment(),
getHorizontalTextPosition(), getVerticalTextPosition(),
lr.getLabelRect(), lr.getIconRect(), lr.getTextRect(), getGap());
}
}
/*
* Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2002-2008 Sun Microsystems, Inc. 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
......@@ -35,7 +35,7 @@ import javax.swing.border.*;
import java.util.Arrays;
import java.util.ArrayList;
import sun.swing.plaf.synth.SynthUI;
import sun.swing.MenuItemLayoutHelper;
/**
* Synth's MenuUI.
......@@ -86,7 +86,7 @@ class SynthMenuUI extends BasicMenuUI implements PropertyChangeListener,
acceleratorDelimiter = style.getString(context, prefix +
".acceleratorDelimiter", "+");
if (useCheckAndArrow()) {
if (MenuItemLayoutHelper.useCheckAndArrow(menuItem)) {
checkIcon = style.getIcon(context, prefix + ".checkIcon");
arrowIcon = style.getIcon(context, prefix + ".arrowIcon");
} else {
......@@ -111,6 +111,16 @@ class SynthMenuUI extends BasicMenuUI implements PropertyChangeListener,
accContext.dispose();
}
public void uninstallUI(JComponent c) {
super.uninstallUI(c);
// Remove values from the parent's Client Properties.
JComponent p = MenuItemLayoutHelper.getMenuItemParent((JMenuItem) c);
if (p != null) {
p.putClientProperty(
SynthMenuItemLayoutHelper.MAX_ACC_OR_ARROW_WIDTH, null);
}
}
protected void uninstallDefaults() {
SynthContext context = getContext(menuItem, ENABLED);
style.uninstallDefaults(context);
......@@ -182,9 +192,11 @@ class SynthMenuUI extends BasicMenuUI implements PropertyChangeListener,
int defaultTextIconGap) {
SynthContext context = getContext(c);
SynthContext accContext = getContext(c, Region.MENU_ITEM_ACCELERATOR);
Dimension value = SynthMenuItemUI.getPreferredMenuItemSize(
context, accContext, c, checkIcon, arrowIcon,
defaultTextIconGap, acceleratorDelimiter);
Dimension value = SynthGraphicsUtils.getPreferredMenuItemSize(
context, accContext, c, checkIcon, arrowIcon,
defaultTextIconGap, acceleratorDelimiter,
MenuItemLayoutHelper.useCheckAndArrow(menuItem),
getPropertyPrefix());
context.dispose();
accContext.dispose();
return value;
......@@ -211,21 +223,12 @@ class SynthMenuUI extends BasicMenuUI implements PropertyChangeListener,
protected void paint(SynthContext context, Graphics g) {
SynthContext accContext = getContext(menuItem,
Region.MENU_ITEM_ACCELERATOR);
SynthStyle style = context.getStyle();
Icon checkIcon;
Icon arrowIcon;
if (useCheckAndArrow()) {
// Refetch the appropriate icons for the current state
String prefix = getPropertyPrefix();
checkIcon = style.getIcon(context, prefix + ".checkIcon");
arrowIcon = style.getIcon(context, prefix + ".arrowIcon");
} else {
// Not needed in this case
checkIcon = null;
arrowIcon = null;
}
SynthMenuItemUI.paint(context, accContext, g, checkIcon, arrowIcon,
acceleratorDelimiter, defaultTextIconGap);
// Refetch the appropriate check indicator for the current state
String prefix = getPropertyPrefix();
Icon checkIcon = style.getIcon(context, prefix + ".checkIcon");
Icon arrowIcon = style.getIcon(context, prefix + ".arrowIcon");
SynthGraphicsUtils.paint(context, accContext, g, checkIcon, arrowIcon,
acceleratorDelimiter, defaultTextIconGap, getPropertyPrefix());
accContext.dispose();
}
......@@ -239,8 +242,4 @@ class SynthMenuUI extends BasicMenuUI implements PropertyChangeListener,
updateStyle((JMenu)e.getSource());
}
}
private boolean useCheckAndArrow() {
return !((JMenu)menuItem).isTopLevelMenu();
}
}
/*
* Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2002-2008 Sun Microsystems, Inc. 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
......@@ -58,34 +58,6 @@ import sun.swing.plaf.synth.SynthUI;
*/
class SynthPopupMenuUI extends BasicPopupMenuUI implements
PropertyChangeListener, SynthUI {
/**
* Maximum size of the text portion of the children menu items.
*/
private int maxTextWidth;
/**
* Maximum size of the icon portion of the children menu items.
*/
private int maxIconWidth;
/**
* Maximum size of the spacing between the text and accelerator
* portions of the children menu items.
*/
private int maxAccelSpacingWidth;
/**
* Maximum size of the text for the accelerator portion of the children
* menu items.
*/
private int maxAcceleratorWidth;
/*
* Maximum icon and text offsets of the children menu items.
*/
private int maxTextOffset;
private int maxIconOffset;
private SynthStyle style;
public static ComponentUI createUI(JComponent x) {
......@@ -153,90 +125,6 @@ class SynthPopupMenuUI extends BasicPopupMenuUI implements
return SynthLookAndFeel.getComponentState(c);
}
/**
* Resets the max text and accerator widths,
* text and icon offsets.
*/
void resetAlignmentHints() {
maxTextWidth = maxIconWidth
= maxAccelSpacingWidth = maxAcceleratorWidth
= maxTextOffset = maxIconOffset = 0;
}
/**
* Adjusts the width needed to display the maximum menu item string.
*
* @param width Text width.
* @return max width
*/
int adjustTextWidth(int width) {
maxTextWidth = Math.max(maxTextWidth, width);
return maxTextWidth;
}
/**
* Adjusts the width needed to display the maximum menu item icon.
*
* @param width Icon width.
* @return max width
*/
int adjustIconWidth(int width) {
maxIconWidth = Math.max(maxIconWidth, width);
return maxIconWidth;
}
/**
* Adjusts the width needed to pad between the maximum menu item
* text and accelerator.
*
* @param width Spacing width.
* @return max width
*/
int adjustAccelSpacingWidth(int width) {
maxAccelSpacingWidth = Math.max(maxAccelSpacingWidth, width);
return maxAccelSpacingWidth;
}
/**
* Adjusts the width needed to display the maximum accelerator.
*
* @param width Text width.
* @return max width
*/
int adjustAcceleratorWidth(int width) {
maxAcceleratorWidth = Math.max(maxAcceleratorWidth, width);
return maxAcceleratorWidth;
}
/**
* Maximum size needed to display accelerators of children menu items.
*/
int getMaxAcceleratorWidth() {
return maxAcceleratorWidth;
}
/**
* Adjusts the text offset needed to align text horizontally.
*
* @param offset Text offset
* @return max offset
*/
int adjustTextOffset(int offset) {
maxTextOffset = Math.max(maxTextOffset, offset);
return maxTextOffset;
}
/**
* Adjusts the icon offset needed to align icons horizontally
*
* @param offset Icon offset
* @return max offset
*/
int adjustIconOffset(int offset) {
maxIconOffset = Math.max(maxIconOffset, offset);
return maxIconOffset;
}
public void update(Graphics g, JComponent c) {
SynthContext context = getContext(c);
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册