1
1
/*
2
- * Copyright (c) 1998, 2021 , 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
@@ -217,16 +239,28 @@ public Insets getBorderInsets(Component c, Insets newInsets) {
217
239
*/
218
240
@ SuppressWarnings ("serial" ) // Superclass is not serializable across versions
219
241
public static class InternalFrameBorder extends AbstractBorder implements UIResource {
220
- private static final int corner = 14 ;
242
+ private static final int CORNER = 14 ;
221
243
222
244
/**
223
245
* Constructs a {@code InternalFrameBorder}.
224
246
*/
225
247
public InternalFrameBorder () {}
226
248
227
- public void paintBorder (Component c , Graphics g , int x , int y ,
228
- int w , int h ) {
249
+ /**
250
+ * Rounds a double to the nearest integer. It rounds 0.5 down,
251
+ * for example 1.5 is rounded to 1.0.
252
+ *
253
+ * @param d number to be rounded
254
+ * @return the rounded value
255
+ */
256
+ private static int roundHalfDown (double d ) {
257
+ double decP = (Math .ceil (d ) - d );
258
+ return (int )((decP == 0.5 ) ? Math .floor (d ) : Math .round (d ));
259
+ }
260
+
229
261
262
+ public void paintBorder (Component c , Graphics g , int x , int y ,
263
+ int w , int h ) {
230
264
Color background ;
231
265
Color highlight ;
232
266
Color shadow ;
@@ -241,41 +275,93 @@ public void paintBorder(Component c, Graphics g, int x, int y,
241
275
shadow = MetalLookAndFeel .getControlInfo ();
242
276
}
243
277
244
- g .setColor (background );
245
- // Draw outermost lines
246
- g .drawLine ( 1 , 0 , w -2 , 0 );
247
- g .drawLine ( 0 , 1 , 0 , h -2 );
248
- g .drawLine ( w -1 , 1 , w -1 , h -2 );
249
- g .drawLine ( 1 , h -1 , w -2 , h -1 );
278
+ Graphics2D g2d = (Graphics2D ) g ;
279
+ AffineTransform at = g2d .getTransform ();
280
+ Stroke oldStk = g2d .getStroke ();
281
+ Color oldColor = g2d .getColor ();
282
+ int stkWidth = 1 ;
283
+
284
+ // if m01 or m10 is non-zero, then there is a rotation or shear
285
+ // skip resetting the transform
286
+ boolean resetTransform = ((at .getShearX () == 0 ) && (at .getShearY () == 0 ));
287
+
288
+ int xtranslation ;
289
+ int ytranslation ;
290
+ int width ;
291
+ int height ;
292
+
293
+ if (resetTransform ) {
294
+ g2d .setTransform (new AffineTransform ());
295
+ stkWidth = roundHalfDown (Math .min (at .getScaleX (), at .getScaleY ()));
296
+
297
+ double xx = at .getScaleX () * x + at .getTranslateX ();
298
+ double yy = at .getScaleY () * y + at .getTranslateY ();
299
+ xtranslation = roundHalfDown (xx );
300
+ ytranslation = roundHalfDown (yy );
301
+ width = roundHalfDown (at .getScaleX () * w + xx ) - xtranslation ;
302
+ height = roundHalfDown (at .getScaleY () * h + yy ) - ytranslation ;
303
+ } else {
304
+ width = w ;
305
+ height = h ;
306
+ xtranslation = x ;
307
+ ytranslation = y ;
308
+ }
309
+ g2d .translate (xtranslation , ytranslation );
250
310
251
- // Draw the bulk of the border
252
- for (int i = 1 ; i < 5 ; i ++) {
253
- g .drawRect (x +i ,y +i ,w -(i *2 )-1 , h -(i *2 )-1 );
254
- }
311
+ // scaled border
312
+ int thickness = (int ) Math .ceil (4 * at .getScaleX ());
255
313
256
- if (c instanceof JInternalFrame &&
257
- ((JInternalFrame )c ).isResizable ()) {
258
- g .setColor (highlight );
259
- // Draw the Long highlight lines
260
- g .drawLine ( corner +1 , 3 , w -corner , 3 );
261
- g .drawLine ( 3 , corner +1 , 3 , h -corner );
262
- g .drawLine ( w -2 , corner +1 , w -2 , h -corner );
263
- g .drawLine ( corner +1 , h -2 , w -corner , h -2 );
264
-
265
- g .setColor (shadow );
266
- // Draw the Long shadow lines
267
- g .drawLine ( corner , 2 , w -corner -1 , 2 );
268
- g .drawLine ( 2 , corner , 2 , h -corner -1 );
269
- g .drawLine ( w -3 , corner , w -3 , h -corner -1 );
270
- g .drawLine ( corner , h -3 , w -corner -1 , h -3 );
271
- }
314
+ g .setColor (background );
315
+ // Draw the bulk of the border
316
+ for (int i = 0 ; i <= thickness ; i ++) {
317
+ g .drawRect (i , i , width - (i * 2 ), height - (i * 2 ));
318
+ }
272
319
273
- }
320
+ if (c instanceof JInternalFrame && ((JInternalFrame )c ).isResizable ()) {
321
+ // set new stroke to draw shadow and highlight lines
322
+ g2d .setStroke (new BasicStroke ((float ) stkWidth ));
274
323
275
- public Insets getBorderInsets (Component c , Insets newInsets ) {
276
- newInsets .set (5 , 5 , 5 , 5 );
277
- return newInsets ;
278
- }
324
+ // midpoint at which highlight & shadow lines
325
+ // are positioned on the border
326
+ int midPoint = thickness / 2 ;
327
+ int offset = ((at .getScaleX () - stkWidth ) >= 0 && stkWidth % 2 != 0 ) ? 1 : 0 ;
328
+ int loc1 = thickness % 2 == 0 ? midPoint + stkWidth / 2 - stkWidth : midPoint ;
329
+ int loc2 = thickness % 2 == 0 ? midPoint + stkWidth / 2 : midPoint + stkWidth ;
330
+ // scaled corner
331
+ int corner = (int ) Math .round (CORNER * at .getScaleX ());
332
+
333
+ // Draw the Long highlight lines
334
+ g .setColor (highlight );
335
+ g .drawLine (corner + 1 , loc2 , width - corner , loc2 ); //top
336
+ g .drawLine (loc2 , corner + 1 , loc2 , height - corner ); //left
337
+ g .drawLine ((width - offset ) - loc1 , corner + 1 ,
338
+ (width - offset ) - loc1 , height - corner ); //right
339
+ g .drawLine (corner + 1 , (height - offset ) - loc1 ,
340
+ width - corner , (height - offset ) - loc1 ); //bottom
341
+
342
+ // Draw the Long shadow lines
343
+ g .setColor (shadow );
344
+ g .drawLine (corner , loc1 , width - corner - 1 , loc1 );
345
+ g .drawLine (loc1 , corner , loc1 , height - corner - 1 );
346
+ g .drawLine ((width - offset ) - loc2 , corner ,
347
+ (width - offset ) - loc2 , height - corner - 1 );
348
+ g .drawLine (corner , (height - offset ) - loc2 ,
349
+ width - corner - 1 , (height - offset ) - loc2 );
350
+ }
351
+
352
+ // restore previous transform
353
+ g2d .translate (-xtranslation , -ytranslation );
354
+ if (resetTransform ) {
355
+ g2d .setColor (oldColor );
356
+ g2d .setTransform (at );
357
+ g2d .setStroke (oldStk );
358
+ }
359
+ }
360
+
361
+ public Insets getBorderInsets (Component c , Insets newInsets ) {
362
+ newInsets .set (4 , 4 , 4 , 4 );
363
+ return newInsets ;
364
+ }
279
365
}
280
366
281
367
/**
0 commit comments