From 87d7e976cbb9a4441f6f215252383b41b2b69f97 Mon Sep 17 00:00:00 2001
From: Tejesh R
Date: Thu, 3 Aug 2023 04:44:41 +0000
Subject: [PATCH] 8311031: JTable header border vertical lines are not aligned
with data grid lines
Reviewed-by: abhiscxk, psadhukhan, aivanov
---
.../javax/swing/plaf/metal/MetalBorders.java | 8 +-
.../TableHeaderBorderPositionTest.java | 108 ++++++++++++++++++
2 files changed, 112 insertions(+), 4 deletions(-)
create mode 100644 test/jdk/javax/swing/JTableHeader/TableHeaderBorderPositionTest.java
diff --git a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalBorders.java b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalBorders.java
index df2af1aee09..95cff96dad6 100644
--- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalBorders.java
+++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalBorders.java
@@ -1108,11 +1108,11 @@ public class MetalBorders {
g.translate( x, y );
g.setColor( MetalLookAndFeel.getControlDarkShadow() );
- g.drawLine( w-1, 0, w-1, h-1 );
- g.drawLine( 1, h-1, w-1, h-1 );
+ SwingUtilities2.drawVLine(g, w-1, 0, h-1);
+ SwingUtilities2.drawHLine(g, 1, w-1, h-1);
g.setColor( MetalLookAndFeel.getControlHighlight() );
- g.drawLine( 0, 0, w-2, 0 );
- g.drawLine( 0, 0, 0, h-2 );
+ SwingUtilities2.drawHLine(g, 0, w-2, 0);
+ SwingUtilities2.drawVLine(g, 0, 0, h-2);
g.translate( -x, -y );
}
diff --git a/test/jdk/javax/swing/JTableHeader/TableHeaderBorderPositionTest.java b/test/jdk/javax/swing/JTableHeader/TableHeaderBorderPositionTest.java
new file mode 100644
index 00000000000..86c844f52f4
--- /dev/null
+++ b/test/jdk/javax/swing/JTableHeader/TableHeaderBorderPositionTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.imageio.ImageIO;
+import javax.swing.JTable;
+import javax.swing.SwingUtilities;
+import javax.swing.table.JTableHeader;
+import javax.swing.UIManager;
+
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+
+import java.io.File;
+import java.io.IOException;
+
+/*
+ * @test
+ * @bug 8311031
+ * @summary Test to validate JTable header border vertical line is
+ * aligned with data grid lines (Metal L&F).
+ * @run main TableHeaderBorderPositionTest
+ */
+public class TableHeaderBorderPositionTest {
+ private static final double SCALE = 2.25;
+
+ public static void main(String[] args) throws Exception {
+ UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
+ String[][] data = {
+ {"1", "1"}
+ };
+
+ String[] columnNames = {"Size", "Size"};
+
+ JTable table = new JTable(data, columnNames);
+ Dimension tableSize = table.getPreferredSize();
+ table.setSize(tableSize);
+
+ final JTableHeader header = table.getTableHeader();
+ Dimension headerSize = header.getPreferredSize();
+ header.setSize(headerSize);
+
+ Dimension size = new Dimension(Math.max(headerSize.width, tableSize.width),
+ headerSize.height + tableSize.height);
+
+ BufferedImage bufferedImage =
+ new BufferedImage((int)Math.ceil(size.width * SCALE),
+ (int)Math.ceil(size.height * SCALE),
+ BufferedImage.TYPE_INT_RGB);
+
+ Graphics2D g2d = bufferedImage.createGraphics();
+ g2d.scale(SCALE, SCALE);
+
+ try {
+ header.paint(g2d);
+ g2d.translate(0, header.getHeight());
+ table.paint(g2d);
+ } finally {
+ g2d.dispose();
+ }
+
+ int verticalLineCol = (int)(table.getTableHeader()
+ .getColumnModel()
+ .getColumn(0)
+ .getWidth() * SCALE) - 2;
+ int expectedRGB = bufferedImage.getRGB(verticalLineCol, 0);
+ int maxHeight = (int)(((double)table.getTableHeader().getHeight() * SCALE)
+ + ((double)table.getRowHeight() * SCALE));
+
+ for (int y = 0; y < maxHeight; y++) {
+ for (int x = verticalLineCol; x < verticalLineCol + 3; x++) {
+ if (expectedRGB != bufferedImage.getRGB(x, y)) {
+ saveImage(bufferedImage, "failureImage.png");
+ throw new RuntimeException("Test Failed at <" + x + ", " + y + ">");
+ }
+ }
+ }
+ System.out.println("Test Passed");
+ }
+
+ private static void saveImage(BufferedImage image, String fileName) {
+ try {
+ ImageIO.write(image, "png", new File(fileName));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}