Skip to content

Commit 7fb1fb0

Browse files
committed
8015739: Background of JInternalFrame is located out of JInternalFrame
Backport-of: f857f795a9fc8b116bfc6b039114051061950e28
1 parent fce02ad commit 7fb1fb0

File tree

2 files changed

+396
-44
lines changed

2 files changed

+396
-44
lines changed

src/java.desktop/share/classes/javax/swing/plaf/metal/MetalBorders.java

Lines changed: 130 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
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.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -25,24 +25,46 @@
2525

2626
package javax.swing.plaf.metal;
2727

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;
3629
import java.awt.Color;
30+
import java.awt.Component;
3731
import java.awt.Dialog;
3832
import java.awt.Frame;
3933
import java.awt.Graphics;
34+
import java.awt.Graphics2D;
35+
import java.awt.Insets;
36+
import java.awt.Stroke;
4037
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;
4164

4265
import sun.swing.StringUIClientPropertyKey;
4366
import sun.swing.SwingUtilities2;
4467

45-
4668
/**
4769
* Factory object that can vend Borders appropriate for the metal L & F.
4870
* @author Steve Wilson
@@ -218,16 +240,28 @@ public Insets getBorderInsets(Component c, Insets newInsets) {
218240
*/
219241
@SuppressWarnings("serial") // Superclass is not serializable across versions
220242
public static class InternalFrameBorder extends AbstractBorder implements UIResource {
221-
private static final int corner = 14;
243+
private static final int CORNER = 14;
222244

223245
/**
224246
* Constructs a {@code InternalFrameBorder}.
225247
*/
226248
public InternalFrameBorder() {}
227249

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+
230262

263+
public void paintBorder(Component c, Graphics g, int x, int y,
264+
int w, int h) {
231265
Color background;
232266
Color highlight;
233267
Color shadow;
@@ -242,41 +276,93 @@ public void paintBorder(Component c, Graphics g, int x, int y,
242276
shadow = MetalLookAndFeel.getControlInfo();
243277
}
244278

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);
251311

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());
256314

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+
}
273320

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));
275324

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+
}
280366
}
281367

282368
/**

0 commit comments

Comments
 (0)