1 /* |
|
2 * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. Oracle designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Oracle in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 * or visit www.oracle.com if you need additional information or have any |
|
23 * questions. |
|
24 */ |
|
25 |
|
26 package com.sun.java.swing.plaf.windows; |
|
27 |
|
28 import sun.swing.SwingUtilities2; |
|
29 |
|
30 import java.awt.*; |
|
31 |
|
32 import javax.swing.*; |
|
33 import javax.swing.plaf.UIResource; |
|
34 |
|
35 import static com.sun.java.swing.plaf.windows.TMSchema.*; |
|
36 |
|
37 /** |
|
38 * A collection of static utility methods used for rendering the Windows look |
|
39 * and feel. |
|
40 * |
|
41 * @author Mark Davidson |
|
42 * @since 1.4 |
|
43 */ |
|
44 public class WindowsGraphicsUtils { |
|
45 |
|
46 /** |
|
47 * Renders a text String in Windows without the mnemonic. |
|
48 * This is here because the WindowsUI hierarchy doesn't match the Component hierarchy. All |
|
49 * the overriden paintText methods of the ButtonUI delegates will call this static method. |
|
50 * |
|
51 * @param g Graphics context |
|
52 * @param b Current button to render |
|
53 * @param textRect Bounding rectangle to render the text. |
|
54 * @param text String to render |
|
55 */ |
|
56 public static void paintText(Graphics g, AbstractButton b, |
|
57 Rectangle textRect, String text, |
|
58 int textShiftOffset) { |
|
59 FontMetrics fm = SwingUtilities2.getFontMetrics(b, g); |
|
60 |
|
61 int mnemIndex = b.getDisplayedMnemonicIndex(); |
|
62 // W2K Feature: Check to see if the Underscore should be rendered. |
|
63 if (WindowsLookAndFeel.isMnemonicHidden() == true) { |
|
64 mnemIndex = -1; |
|
65 } |
|
66 |
|
67 XPStyle xp = XPStyle.getXP(); |
|
68 if (xp != null && !(b instanceof JMenuItem)) { |
|
69 paintXPText(b, g, textRect.x + textShiftOffset, |
|
70 textRect.y + fm.getAscent() + textShiftOffset, |
|
71 text, mnemIndex); |
|
72 } else { |
|
73 paintClassicText(b, g, textRect.x + textShiftOffset, |
|
74 textRect.y + fm.getAscent() + textShiftOffset, |
|
75 text, mnemIndex); |
|
76 } |
|
77 } |
|
78 |
|
79 static void paintClassicText(AbstractButton b, Graphics g, int x, int y, |
|
80 String text, int mnemIndex) { |
|
81 ButtonModel model = b.getModel(); |
|
82 |
|
83 /* Draw the Text */ |
|
84 Color color = b.getForeground(); |
|
85 if(model.isEnabled()) { |
|
86 /*** paint the text normally */ |
|
87 if(!(b instanceof JMenuItem && model.isArmed()) |
|
88 && !(b instanceof JMenu && (model.isSelected() || model.isRollover()))) { |
|
89 /* We shall not set foreground color for selected menu or |
|
90 * armed menuitem. Foreground must be set in appropriate |
|
91 * Windows* class because these colors passes from |
|
92 * BasicMenuItemUI as protected fields and we can't |
|
93 * reach them from this class */ |
|
94 g.setColor(b.getForeground()); |
|
95 } |
|
96 SwingUtilities2.drawStringUnderlineCharAt(b, g,text, mnemIndex, x, y); |
|
97 } else { /*** paint the text disabled ***/ |
|
98 color = getDisabledTextColor(b); |
|
99 if (color == null) { |
|
100 color = UIManager.getColor("Button.shadow"); |
|
101 } |
|
102 Color shadow = UIManager.getColor("Button.disabledShadow"); |
|
103 if(model.isArmed()) { |
|
104 color = UIManager.getColor("Button.disabledForeground"); |
|
105 } else { |
|
106 if (shadow == null) { |
|
107 shadow = b.getBackground().darker(); |
|
108 } |
|
109 g.setColor(shadow); |
|
110 SwingUtilities2.drawStringUnderlineCharAt(b, g, text, mnemIndex, |
|
111 x + 1, y + 1); |
|
112 } |
|
113 if (color == null) { |
|
114 color = b.getBackground().brighter(); |
|
115 } |
|
116 g.setColor(color); |
|
117 SwingUtilities2.drawStringUnderlineCharAt(b, g, text, mnemIndex, x, y); |
|
118 } |
|
119 } |
|
120 |
|
121 private static Color getDisabledTextColor(AbstractButton b) { |
|
122 if (b instanceof JCheckBox) { |
|
123 return UIManager.getColor("CheckBox.disabledText"); |
|
124 } else if (b instanceof JRadioButton) { |
|
125 return UIManager.getColor("RadioButton.disabledText"); |
|
126 } else if (b instanceof JToggleButton) { |
|
127 return UIManager.getColor("ToggleButton.disabledText"); |
|
128 } else if (b instanceof JButton) { |
|
129 return UIManager.getColor("Button.disabledText"); |
|
130 } |
|
131 return null; |
|
132 } |
|
133 |
|
134 static void paintXPText(AbstractButton b, Graphics g, int x, int y, |
|
135 String text, int mnemIndex) { |
|
136 Part part = WindowsButtonUI.getXPButtonType(b); |
|
137 State state = WindowsButtonUI.getXPButtonState(b); |
|
138 paintXPText(b, part, state, g, x, y, text, mnemIndex); |
|
139 } |
|
140 |
|
141 static void paintXPText(AbstractButton b, Part part, State state, |
|
142 Graphics g, int x, int y, String text, int mnemIndex) { |
|
143 XPStyle xp = XPStyle.getXP(); |
|
144 if (xp == null) { |
|
145 return; |
|
146 } |
|
147 Color textColor; |
|
148 if (b.isEnabled()) { |
|
149 textColor = b.getForeground(); |
|
150 } |
|
151 else { |
|
152 textColor = getDisabledTextColor(b); |
|
153 } |
|
154 |
|
155 if (textColor == null || textColor instanceof UIResource) { |
|
156 textColor = xp.getColor(b, part, state, Prop.TEXTCOLOR, b.getForeground()); |
|
157 // to work around an apparent bug in Windows, use the pushbutton |
|
158 // color for disabled toolbar buttons if the disabled color is the |
|
159 // same as the enabled color |
|
160 if (part == Part.TP_BUTTON && state == State.DISABLED) { |
|
161 Color enabledColor = xp.getColor(b, part, State.NORMAL, |
|
162 Prop.TEXTCOLOR, b.getForeground()); |
|
163 if(textColor.equals(enabledColor)) { |
|
164 textColor = xp.getColor(b, Part.BP_PUSHBUTTON, state, |
|
165 Prop.TEXTCOLOR, textColor); |
|
166 } |
|
167 } |
|
168 // only draw shadow if developer hasn't changed the foreground color |
|
169 // and if the current style has text shadows. |
|
170 TypeEnum shadowType = xp.getTypeEnum(b, part, |
|
171 state, Prop.TEXTSHADOWTYPE); |
|
172 if (shadowType == TypeEnum.TST_SINGLE || |
|
173 shadowType == TypeEnum.TST_CONTINUOUS) { |
|
174 Color shadowColor = xp.getColor(b, part, state, |
|
175 Prop.TEXTSHADOWCOLOR, Color.black); |
|
176 Point offset = xp.getPoint(b, part, state, Prop.TEXTSHADOWOFFSET); |
|
177 if (offset != null) { |
|
178 g.setColor(shadowColor); |
|
179 SwingUtilities2.drawStringUnderlineCharAt(b, g, text, mnemIndex, |
|
180 x + offset.x, |
|
181 y + offset.y); |
|
182 } |
|
183 } |
|
184 } |
|
185 |
|
186 g.setColor(textColor); |
|
187 SwingUtilities2.drawStringUnderlineCharAt(b, g, text, mnemIndex, x, y); |
|
188 } |
|
189 |
|
190 static boolean isLeftToRight(Component c) { |
|
191 return c.getComponentOrientation().isLeftToRight(); |
|
192 } |
|
193 |
|
194 /* |
|
195 * Repaints all the components with the mnemonics in the given window and |
|
196 * all its owned windows. |
|
197 */ |
|
198 static void repaintMnemonicsInWindow(Window w) { |
|
199 if(w == null || !w.isShowing()) { |
|
200 return; |
|
201 } |
|
202 |
|
203 Window[] ownedWindows = w.getOwnedWindows(); |
|
204 for(int i=0;i<ownedWindows.length;i++) { |
|
205 repaintMnemonicsInWindow(ownedWindows[i]); |
|
206 } |
|
207 |
|
208 repaintMnemonicsInContainer(w); |
|
209 } |
|
210 |
|
211 /* |
|
212 * Repaints all the components with the mnemonics in container. |
|
213 * Recursively searches for all the subcomponents. |
|
214 */ |
|
215 static void repaintMnemonicsInContainer(Container cont) { |
|
216 Component c; |
|
217 for(int i=0; i<cont.getComponentCount(); i++) { |
|
218 c = cont.getComponent(i); |
|
219 if(c == null || !c.isVisible()) { |
|
220 continue; |
|
221 } |
|
222 if(c instanceof AbstractButton |
|
223 && ((AbstractButton)c).getMnemonic() != '\0') { |
|
224 c.repaint(); |
|
225 continue; |
|
226 } else if(c instanceof JLabel |
|
227 && ((JLabel)c).getDisplayedMnemonic() != '\0') { |
|
228 c.repaint(); |
|
229 continue; |
|
230 } |
|
231 if(c instanceof Container) { |
|
232 repaintMnemonicsInContainer((Container)c); |
|
233 } |
|
234 } |
|
235 } |
|
236 } |
|