1
1
/*
2
- * Copyright (c) 1998, 2015 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 1998, 2022 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
25
25
26
26
package javax .swing .plaf .metal ;
27
27
28
- import javax .swing .*;
29
- import javax .swing .border .*;
30
- import javax .swing .plaf .*;
31
- import javax .swing .plaf .basic .BasicBorders ;
32
- import javax .swing .text .JTextComponent ;
33
-
34
- import java .awt .Component ;
35
- import java .awt .Insets ;
28
+ import java .awt .BasicStroke ;
36
29
import java .awt .Color ;
30
+ import java .awt .Component ;
37
31
import java .awt .Dialog ;
38
32
import java .awt .Frame ;
39
33
import java .awt .Graphics ;
34
+ import java .awt .Graphics2D ;
35
+ import java .awt .Insets ;
36
+ import java .awt .Stroke ;
40
37
import java .awt .Window ;
38
+ import java .awt .geom .AffineTransform ;
39
+
40
+ import javax .swing .AbstractButton ;
41
+ import javax .swing .ButtonModel ;
42
+ import javax .swing .JButton ;
43
+ import javax .swing .JComponent ;
44
+ import javax .swing .JInternalFrame ;
45
+ import javax .swing .JMenu ;
46
+ import javax .swing .JMenuBar ;
47
+ import javax .swing .JMenuItem ;
48
+ import javax .swing .JOptionPane ;
49
+ import javax .swing .JScrollPane ;
50
+ import javax .swing .JToolBar ;
51
+ import javax .swing .SwingConstants ;
52
+ import javax .swing .SwingUtilities ;
53
+ import javax .swing .UIManager ;
54
+ import javax .swing .border .AbstractBorder ;
55
+ import javax .swing .border .Border ;
56
+ import javax .swing .border .CompoundBorder ;
57
+ import javax .swing .border .EmptyBorder ;
58
+ import javax .swing .border .LineBorder ;
59
+ import javax .swing .border .MatteBorder ;
60
+ import javax .swing .plaf .BorderUIResource ;
61
+ import javax .swing .plaf .UIResource ;
62
+ import javax .swing .plaf .basic .BasicBorders ;
63
+ import javax .swing .text .JTextComponent ;
41
64
42
65
import sun .swing .StringUIClientPropertyKey ;
43
66
import sun .swing .SwingUtilities2 ;
44
67
45
-
46
68
/**
47
69
* Factory object that can vend Borders appropriate for the metal L & F.
48
70
* @author Steve Wilson
@@ -218,16 +240,28 @@ public Insets getBorderInsets(Component c, Insets newInsets) {
218
240
*/
219
241
@ SuppressWarnings ("serial" ) // Superclass is not serializable across versions
220
242
public static class InternalFrameBorder extends AbstractBorder implements UIResource {
221
- private static final int corner = 14 ;
243
+ private static final int CORNER = 14 ;
222
244
223
245
/**
224
246
* Constructs a {@code InternalFrameBorder}.
225
247
*/
226
248
public InternalFrameBorder () {}
227
249
228
- public void paintBorder (Component c , Graphics g , int x , int y ,
229
- int w , int h ) {
250
+ /**
251
+ * Rounds a double to the nearest integer. It rounds 0.5 down,
252
+ * for example 1.5 is rounded to 1.0.
253
+ *
254
+ * @param d number to be rounded
255
+ * @return the rounded value
256
+ */
257
+ private static int roundHalfDown (double d ) {
258
+ double decP = (Math .ceil (d ) - d );
259
+ return (int )((decP == 0.5 ) ? Math .floor (d ) : Math .round (d ));
260
+ }
261
+
230
262
263
+ public void paintBorder (Component c , Graphics g , int x , int y ,
264
+ int w , int h ) {
231
265
Color background ;
232
266
Color highlight ;
233
267
Color shadow ;
@@ -242,41 +276,93 @@ public void paintBorder(Component c, Graphics g, int x, int y,
242
276
shadow = MetalLookAndFeel .getControlInfo ();
243
277
}
244
278
245
- g .setColor (background );
246
- // Draw outermost lines
247
- g .drawLine ( 1 , 0 , w -2 , 0 );
248
- g .drawLine ( 0 , 1 , 0 , h -2 );
249
- g .drawLine ( w -1 , 1 , w -1 , h -2 );
250
- g .drawLine ( 1 , h -1 , w -2 , h -1 );
279
+ Graphics2D g2d = (Graphics2D ) g ;
280
+ AffineTransform at = g2d .getTransform ();
281
+ Stroke oldStk = g2d .getStroke ();
282
+ Color oldColor = g2d .getColor ();
283
+ int stkWidth = 1 ;
284
+
285
+ // if m01 or m10 is non-zero, then there is a rotation or shear
286
+ // skip resetting the transform
287
+ boolean resetTransform = ((at .getShearX () == 0 ) && (at .getShearY () == 0 ));
288
+
289
+ int xtranslation ;
290
+ int ytranslation ;
291
+ int width ;
292
+ int height ;
293
+
294
+ if (resetTransform ) {
295
+ g2d .setTransform (new AffineTransform ());
296
+ stkWidth = roundHalfDown (Math .min (at .getScaleX (), at .getScaleY ()));
297
+
298
+ double xx = at .getScaleX () * x + at .getTranslateX ();
299
+ double yy = at .getScaleY () * y + at .getTranslateY ();
300
+ xtranslation = roundHalfDown (xx );
301
+ ytranslation = roundHalfDown (yy );
302
+ width = roundHalfDown (at .getScaleX () * w + xx ) - xtranslation ;
303
+ height = roundHalfDown (at .getScaleY () * h + yy ) - ytranslation ;
304
+ } else {
305
+ width = w ;
306
+ height = h ;
307
+ xtranslation = x ;
308
+ ytranslation = y ;
309
+ }
310
+ g2d .translate (xtranslation , ytranslation );
251
311
252
- // Draw the bulk of the border
253
- for (int i = 1 ; i < 5 ; i ++) {
254
- g .drawRect (x +i ,y +i ,w -(i *2 )-1 , h -(i *2 )-1 );
255
- }
312
+ // scaled border
313
+ int thickness = (int ) Math .ceil (4 * at .getScaleX ());
256
314
257
- if (c instanceof JInternalFrame &&
258
- ((JInternalFrame )c ).isResizable ()) {
259
- g .setColor (highlight );
260
- // Draw the Long highlight lines
261
- g .drawLine ( corner +1 , 3 , w -corner , 3 );
262
- g .drawLine ( 3 , corner +1 , 3 , h -corner );
263
- g .drawLine ( w -2 , corner +1 , w -2 , h -corner );
264
- g .drawLine ( corner +1 , h -2 , w -corner , h -2 );
265
-
266
- g .setColor (shadow );
267
- // Draw the Long shadow lines
268
- g .drawLine ( corner , 2 , w -corner -1 , 2 );
269
- g .drawLine ( 2 , corner , 2 , h -corner -1 );
270
- g .drawLine ( w -3 , corner , w -3 , h -corner -1 );
271
- g .drawLine ( corner , h -3 , w -corner -1 , h -3 );
272
- }
315
+ g .setColor (background );
316
+ // Draw the bulk of the border
317
+ for (int i = 0 ; i <= thickness ; i ++) {
318
+ g .drawRect (i , i , width - (i * 2 ), height - (i * 2 ));
319
+ }
273
320
274
- }
321
+ if (c instanceof JInternalFrame && ((JInternalFrame )c ).isResizable ()) {
322
+ // set new stroke to draw shadow and highlight lines
323
+ g2d .setStroke (new BasicStroke ((float ) stkWidth ));
275
324
276
- public Insets getBorderInsets (Component c , Insets newInsets ) {
277
- newInsets .set (5 , 5 , 5 , 5 );
278
- return newInsets ;
279
- }
325
+ // midpoint at which highlight & shadow lines
326
+ // are positioned on the border
327
+ int midPoint = thickness / 2 ;
328
+ int offset = ((at .getScaleX () - stkWidth ) >= 0 && stkWidth % 2 != 0 ) ? 1 : 0 ;
329
+ int loc1 = thickness % 2 == 0 ? midPoint + stkWidth / 2 - stkWidth : midPoint ;
330
+ int loc2 = thickness % 2 == 0 ? midPoint + stkWidth / 2 : midPoint + stkWidth ;
331
+ // scaled corner
332
+ int corner = (int ) Math .round (CORNER * at .getScaleX ());
333
+
334
+ // Draw the Long highlight lines
335
+ g .setColor (highlight );
336
+ g .drawLine (corner + 1 , loc2 , width - corner , loc2 ); //top
337
+ g .drawLine (loc2 , corner + 1 , loc2 , height - corner ); //left
338
+ g .drawLine ((width - offset ) - loc1 , corner + 1 ,
339
+ (width - offset ) - loc1 , height - corner ); //right
340
+ g .drawLine (corner + 1 , (height - offset ) - loc1 ,
341
+ width - corner , (height - offset ) - loc1 ); //bottom
342
+
343
+ // Draw the Long shadow lines
344
+ g .setColor (shadow );
345
+ g .drawLine (corner , loc1 , width - corner - 1 , loc1 );
346
+ g .drawLine (loc1 , corner , loc1 , height - corner - 1 );
347
+ g .drawLine ((width - offset ) - loc2 , corner ,
348
+ (width - offset ) - loc2 , height - corner - 1 );
349
+ g .drawLine (corner , (height - offset ) - loc2 ,
350
+ width - corner - 1 , (height - offset ) - loc2 );
351
+ }
352
+
353
+ // restore previous transform
354
+ g2d .translate (-xtranslation , -ytranslation );
355
+ if (resetTransform ) {
356
+ g2d .setColor (oldColor );
357
+ g2d .setTransform (at );
358
+ g2d .setStroke (oldStk );
359
+ }
360
+ }
361
+
362
+ public Insets getBorderInsets (Component c , Insets newInsets ) {
363
+ newInsets .set (4 , 4 , 4 , 4 );
364
+ return newInsets ;
365
+ }
280
366
}
281
367
282
368
/**
0 commit comments