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 javax.swing.plaf.basic.*;
29 import javax.swing.border.*;
30 import javax.swing.plaf.*;
31 import javax.swing.*;
32
33 import java.awt.*;
34
35 import static com.sun.java.swing.plaf.windows.TMSchema.*;
36 import static com.sun.java.swing.plaf.windows.TMSchema.Part.*;
37 import static com.sun.java.swing.plaf.windows.XPStyle.Skin;
38 import sun.awt.AppContext;
39
40
41 /**
42 * Windows button.
43 * <p>
44 * <strong>Warning:</strong>
45 * Serialized objects of this class will not be compatible with
46 * future Swing releases. The current serialization support is appropriate
47 * for short term storage or RMI between applications running the same
48 * version of Swing. A future release of Swing will provide support for
49 * long term persistence.
50 *
51 * @author Jeff Dinkins
52 *
53 */
54 public class WindowsButtonUI extends BasicButtonUI
55 {
56 protected int dashedRectGapX;
57 protected int dashedRectGapY;
144 /* Ensure that the width and height of the button is odd,
145 * to allow for the focus line if focus is painted
146 */
147 AbstractButton b = (AbstractButton)c;
148 if (d != null && b.isFocusPainted()) {
149 if(d.width % 2 == 0) { d.width += 1; }
150 if(d.height % 2 == 0) { d.height += 1; }
151 }
152 return d;
153 }
154
155
156 /* These rectangles/insets are allocated once for all
157 * ButtonUI.paint() calls. Re-using rectangles rather than
158 * allocating them in each paint call substantially reduced the time
159 * it took paint to run. Obviously, this method can't be re-entered.
160 */
161 private Rectangle viewRect = new Rectangle();
162
163 public void paint(Graphics g, JComponent c) {
164 if (XPStyle.getXP() != null) {
165 WindowsButtonUI.paintXPButtonBackground(g, c);
166 }
167 super.paint(g, c);
168 }
169
170 static Part getXPButtonType(AbstractButton b) {
171 if(b instanceof JCheckBox) {
172 return Part.BP_CHECKBOX;
173 }
174 if(b instanceof JRadioButton) {
175 return Part.BP_RADIOBUTTON;
176 }
177 boolean toolbar = (b.getParent() instanceof JToolBar);
178 return toolbar ? Part.TP_BUTTON : Part.BP_PUSHBUTTON;
179 }
180
181 static State getXPButtonState(AbstractButton b) {
182 Part part = getXPButtonType(b);
183 ButtonModel model = b.getModel();
184 State state = State.NORMAL;
185 switch (part) {
186 case BP_RADIOBUTTON:
187 /* falls through */
188 case BP_CHECKBOX:
189 if (! model.isEnabled()) {
190 state = (model.isSelected()) ? State.CHECKEDDISABLED
191 : State.UNCHECKEDDISABLED;
192 } else if (model.isPressed() && model.isArmed()) {
193 state = (model.isSelected()) ? State.CHECKEDPRESSED
194 : State.UNCHECKEDPRESSED;
195 } else if (model.isRollover()) {
196 state = (model.isSelected()) ? State.CHECKEDHOT
197 : State.UNCHECKEDHOT;
261 int dh = d.height;
262
263 Border border = c.getBorder();
264 Insets insets;
265 if (border != null) {
266 // Note: The border may be compound, containing an outer
267 // opaque border (supplied by the application), plus an
268 // inner transparent margin border. We want to size the
269 // background to fill the transparent part, but stay
270 // inside the opaque part.
271 insets = WindowsButtonUI.getOpaqueInsets(border, c);
272 } else {
273 insets = c.getInsets();
274 }
275 if (insets != null) {
276 dx += insets.left;
277 dy += insets.top;
278 dw -= (insets.left + insets.right);
279 dh -= (insets.top + insets.bottom);
280 }
281 skin.paintSkin(g, dx, dy, dw, dh, state);
282 }
283 }
284
285 /**
286 * returns - b.getBorderInsets(c) if border is opaque
287 * - null if border is completely non-opaque
288 * - somewhere inbetween if border is compound and
289 * outside border is opaque and inside isn't
290 */
291 private static Insets getOpaqueInsets(Border b, Component c) {
292 if (b == null) {
293 return null;
294 }
295 if (b.isBorderOpaque()) {
296 return b.getBorderInsets(c);
297 } else if (b instanceof CompoundBorder) {
298 CompoundBorder cb = (CompoundBorder)b;
299 Insets iOut = getOpaqueInsets(cb.getOutsideBorder(), c);
300 if (iOut != null && iOut.equals(cb.getOutsideBorder().getBorderInsets(c))) {
301 // Outside border is opaque, keep looking
|
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 javax.swing.plaf.basic.*;
29 import javax.swing.border.*;
30 import javax.swing.plaf.*;
31 import javax.swing.*;
32
33 import java.awt.*;
34
35 import static com.sun.java.swing.plaf.windows.TMSchema.*;
36 import static com.sun.java.swing.plaf.windows.TMSchema.Part.*;
37 import static com.sun.java.swing.plaf.windows.XPStyle.Skin;
38 import static java.lang.Boolean.FALSE;
39 import static java.lang.Boolean.TRUE;
40 import sun.awt.AppContext;
41
42
43 /**
44 * Windows button.
45 * <p>
46 * <strong>Warning:</strong>
47 * Serialized objects of this class will not be compatible with
48 * future Swing releases. The current serialization support is appropriate
49 * for short term storage or RMI between applications running the same
50 * version of Swing. A future release of Swing will provide support for
51 * long term persistence.
52 *
53 * @author Jeff Dinkins
54 *
55 */
56 public class WindowsButtonUI extends BasicButtonUI
57 {
58 protected int dashedRectGapX;
59 protected int dashedRectGapY;
146 /* Ensure that the width and height of the button is odd,
147 * to allow for the focus line if focus is painted
148 */
149 AbstractButton b = (AbstractButton)c;
150 if (d != null && b.isFocusPainted()) {
151 if(d.width % 2 == 0) { d.width += 1; }
152 if(d.height % 2 == 0) { d.height += 1; }
153 }
154 return d;
155 }
156
157
158 /* These rectangles/insets are allocated once for all
159 * ButtonUI.paint() calls. Re-using rectangles rather than
160 * allocating them in each paint call substantially reduced the time
161 * it took paint to run. Obviously, this method can't be re-entered.
162 */
163 private Rectangle viewRect = new Rectangle();
164
165 public void paint(Graphics g, JComponent c) {
166 AbstractButton b = (AbstractButton)c;
167
168 if(isStateChangeAnimated(b)) {
169 boolean rollover = b.getModel().isRollover();
170 AnimationController anim = AnimationController.getAnimationController();
171 boolean wasRollover = b.getClientProperty("WindowsButtonUI.wasRollover") == TRUE;
172
173 if(rollover != wasRollover) {
174 State currentState = wasRollover?State.HOT:State.NORMAL;
175 State targetState = rollover?State.HOT:State.NORMAL;
176 anim.startAnimation(c, getXPButtonType(b), currentState, targetState, 250);
177 }
178
179 b.putClientProperty("WindowsButtonUI.animateToNullState", !rollover);
180 b.putClientProperty("WindowsButtonUI.wasRollover", rollover);
181 }
182
183 if (XPStyle.getXP() != null) {
184 WindowsButtonUI.paintXPButtonBackground(g, c);
185 }
186 super.paint(g, c);
187 }
188
189 private static boolean isStateChangeAnimated(AbstractButton button) {
190 final String propName = "WindowsButtonUI.animateStateChange";
191
192 if(button.getParent() instanceof JToolBar) {
193 JToolBar toolBar = (JToolBar)button.getParent();
194 if(toolBar.getClientProperty(propName)==TRUE)
195 return true;
196 }
197
198 return button.getClientProperty(propName)==TRUE;
199 }
200
201 static Part getXPButtonType(AbstractButton b) {
202 if(b instanceof JCheckBox) {
203 return Part.BP_CHECKBOX;
204 }
205 if(b instanceof JRadioButton) {
206 return Part.BP_RADIOBUTTON;
207 }
208 boolean toolbar = (b.getParent() instanceof JToolBar);
209 if(b.getClientProperty("WindowsButtonUI.displayAsInToolbar") == TRUE)
210 toolbar = true;
211 return toolbar ? Part.TP_BUTTON : Part.BP_PUSHBUTTON;
212 }
213
214 static State getXPButtonState(AbstractButton b) {
215 Part part = getXPButtonType(b);
216 ButtonModel model = b.getModel();
217 State state = State.NORMAL;
218 switch (part) {
219 case BP_RADIOBUTTON:
220 /* falls through */
221 case BP_CHECKBOX:
222 if (! model.isEnabled()) {
223 state = (model.isSelected()) ? State.CHECKEDDISABLED
224 : State.UNCHECKEDDISABLED;
225 } else if (model.isPressed() && model.isArmed()) {
226 state = (model.isSelected()) ? State.CHECKEDPRESSED
227 : State.UNCHECKEDPRESSED;
228 } else if (model.isRollover()) {
229 state = (model.isSelected()) ? State.CHECKEDHOT
230 : State.UNCHECKEDHOT;
294 int dh = d.height;
295
296 Border border = c.getBorder();
297 Insets insets;
298 if (border != null) {
299 // Note: The border may be compound, containing an outer
300 // opaque border (supplied by the application), plus an
301 // inner transparent margin border. We want to size the
302 // background to fill the transparent part, but stay
303 // inside the opaque part.
304 insets = WindowsButtonUI.getOpaqueInsets(border, c);
305 } else {
306 insets = c.getInsets();
307 }
308 if (insets != null) {
309 dx += insets.left;
310 dy += insets.top;
311 dw -= (insets.left + insets.right);
312 dh -= (insets.top + insets.bottom);
313 }
314
315 if(c.getClientProperty("WindowsButtonUI.animateToNullState") == TRUE)
316 state = null;
317
318 AnimationController.paintSkin(c, skin, g, dx, dy, dw, dh, state);
319 }
320 }
321
322 /**
323 * returns - b.getBorderInsets(c) if border is opaque
324 * - null if border is completely non-opaque
325 * - somewhere inbetween if border is compound and
326 * outside border is opaque and inside isn't
327 */
328 private static Insets getOpaqueInsets(Border b, Component c) {
329 if (b == null) {
330 return null;
331 }
332 if (b.isBorderOpaque()) {
333 return b.getBorderInsets(c);
334 } else if (b instanceof CompoundBorder) {
335 CompoundBorder cb = (CompoundBorder)b;
336 Insets iOut = getOpaqueInsets(cb.getOutsideBorder(), c);
337 if (iOut != null && iOut.equals(cb.getOutsideBorder().getBorderInsets(c))) {
338 // Outside border is opaque, keep looking
|