001: /*
002: * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.java.swing.plaf.windows;
027:
028: import sun.swing.SwingUtilities2;
029:
030: import java.awt.*;
031:
032: import javax.swing.*;
033: import javax.swing.plaf.UIResource;
034:
035: import static com.sun.java.swing.plaf.windows.TMSchema.*;
036:
037: /**
038: * A collection of static utility methods used for rendering the Windows look
039: * and feel.
040: *
041: * @version 1.30 05/05/07
042: * @author Mark Davidson
043: * @since 1.4
044: */
045: public class WindowsGraphicsUtils {
046:
047: /**
048: * Renders a text String in Windows without the mnemonic.
049: * This is here because the WindowsUI hiearchy doesn't match the Component heirarchy. All
050: * the overriden paintText methods of the ButtonUI delegates will call this static method.
051: * <p>
052: * @param g Graphics context
053: * @param b Current button to render
054: * @param textRect Bounding rectangle to render the text.
055: * @param text String to render
056: */
057: public static void paintText(Graphics g, AbstractButton b,
058: Rectangle textRect, String text, int textShiftOffset) {
059: FontMetrics fm = SwingUtilities2.getFontMetrics(b, g);
060:
061: int mnemIndex = b.getDisplayedMnemonicIndex();
062: // W2K Feature: Check to see if the Underscore should be rendered.
063: if (WindowsLookAndFeel.isMnemonicHidden() == true) {
064: mnemIndex = -1;
065: }
066:
067: XPStyle xp = XPStyle.getXP();
068: if (xp != null && !(b instanceof JMenuItem)) {
069: paintXPText(b, g, textRect.x + textShiftOffset, textRect.y
070: + fm.getAscent() + textShiftOffset, text, mnemIndex);
071: } else {
072: paintClassicText(b, g, textRect.x + textShiftOffset,
073: textRect.y + fm.getAscent() + textShiftOffset,
074: text, mnemIndex);
075: }
076: }
077:
078: static void paintClassicText(AbstractButton b, Graphics g, int x,
079: int y, String text, int mnemIndex) {
080: ButtonModel model = b.getModel();
081:
082: /* Draw the Text */
083: Color color = b.getForeground();
084: if (model.isEnabled()) {
085: /*** paint the text normally */
086: if (!(b instanceof JMenuItem && model.isArmed())
087: && !(b instanceof JMenu && (model.isSelected() || model
088: .isRollover()))) {
089: /* We shall not set foreground color for selected menu or
090: * armed menuitem. Foreground must be set in appropriate
091: * Windows* class because these colors passes from
092: * BasicMenuItemUI as protected fields and we can't
093: * reach them from this class */
094: g.setColor(b.getForeground());
095: }
096: SwingUtilities2.drawStringUnderlineCharAt(b, g, text,
097: mnemIndex, x, y);
098: } else {
099: /*** paint the text disabled ***/
100: color = UIManager.getColor("Button.shadow");
101: Color shadow = UIManager.getColor("Button.disabledShadow");
102: if (model.isArmed()) {
103: color = UIManager.getColor("Button.disabledForeground");
104: } else {
105: if (shadow == null) {
106: shadow = b.getBackground().darker();
107: }
108: g.setColor(shadow);
109: SwingUtilities2.drawStringUnderlineCharAt(b, g, text,
110: mnemIndex, x + 1, y + 1);
111: }
112: if (color == null) {
113: color = b.getBackground().brighter();
114: }
115: g.setColor(color);
116: SwingUtilities2.drawStringUnderlineCharAt(b, g, text,
117: mnemIndex, x, y);
118: }
119: }
120:
121: static void paintXPText(AbstractButton b, Graphics g, int x, int y,
122: String text, int mnemIndex) {
123: Part part = WindowsButtonUI.getXPButtonType(b);
124: State state = WindowsButtonUI.getXPButtonState(b);
125: paintXPText(b, part, state, g, x, y, text, mnemIndex);
126: }
127:
128: static void paintXPText(AbstractButton b, Part part, State state,
129: Graphics g, int x, int y, String text, int mnemIndex) {
130: XPStyle xp = XPStyle.getXP();
131: Color textColor = b.getForeground();
132:
133: if (textColor instanceof UIResource) {
134: textColor = xp.getColor(b, part, state, Prop.TEXTCOLOR, b
135: .getForeground());
136: // to work around an apparent bug in Windows, use the pushbutton
137: // color for disabled toolbar buttons if the disabled color is the
138: // same as the enabled color
139: if (part == Part.TP_BUTTON && state == State.DISABLED) {
140: Color enabledColor = xp.getColor(b, part, State.NORMAL,
141: Prop.TEXTCOLOR, b.getForeground());
142: if (textColor.equals(enabledColor)) {
143: textColor = xp.getColor(b, Part.BP_PUSHBUTTON,
144: state, Prop.TEXTCOLOR, textColor);
145: }
146: }
147: // only draw shadow if developer hasn't changed the foreground color
148: // and if the current style has text shadows.
149: TypeEnum shadowType = xp.getTypeEnum(b, part, state,
150: Prop.TEXTSHADOWTYPE);
151: if (shadowType == TypeEnum.TST_SINGLE
152: || shadowType == TypeEnum.TST_CONTINUOUS) {
153: Color shadowColor = xp.getColor(b, part, state,
154: Prop.TEXTSHADOWCOLOR, Color.black);
155: Point offset = xp.getPoint(b, part, state,
156: Prop.TEXTSHADOWOFFSET);
157: if (offset != null) {
158: g.setColor(shadowColor);
159: SwingUtilities2
160: .drawStringUnderlineCharAt(b, g, text,
161: mnemIndex, x + offset.x, y
162: + offset.y);
163: }
164: }
165: }
166:
167: g.setColor(textColor);
168: SwingUtilities2.drawStringUnderlineCharAt(b, g, text,
169: mnemIndex, x, y);
170: }
171:
172: static boolean isLeftToRight(Component c) {
173: return c.getComponentOrientation().isLeftToRight();
174: }
175:
176: /*
177: * Repaints all the components with the mnemonics in the given window and
178: * all its owned windows.
179: */
180: static void repaintMnemonicsInWindow(Window w) {
181: if (w == null || !w.isShowing()) {
182: return;
183: }
184:
185: Window[] ownedWindows = w.getOwnedWindows();
186: for (int i = 0; i < ownedWindows.length; i++) {
187: repaintMnemonicsInWindow(ownedWindows[i]);
188: }
189:
190: repaintMnemonicsInContainer(w);
191: }
192:
193: /*
194: * Repaints all the components with the mnemonics in container.
195: * Recursively searches for all the subcomponents.
196: */
197: static void repaintMnemonicsInContainer(Container cont) {
198: Component c;
199: for (int i = 0; i < cont.getComponentCount(); i++) {
200: c = cont.getComponent(i);
201: if (c == null || !c.isVisible()) {
202: continue;
203: }
204: if (c instanceof AbstractButton
205: && ((AbstractButton) c).getMnemonic() != '\0') {
206: c.repaint();
207: continue;
208: } else if (c instanceof JLabel
209: && ((JLabel) c).getDisplayedMnemonic() != '\0') {
210: c.repaint();
211: continue;
212: }
213: if (c instanceof Container) {
214: repaintMnemonicsInContainer((Container) c);
215: }
216: }
217: }
218: }
|