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