Skip to content

Commit 95bd92a

Browse files
author
Tejesh R
committed
8210807: Printing a JTable with a JScrollPane prints table without rows populated
Reviewed-by: psadhukhan, abhiscxk
1 parent 21cda19 commit 95bd92a

File tree

3 files changed

+195
-6
lines changed

3 files changed

+195
-6
lines changed

src/java.desktop/share/classes/javax/swing/JViewport.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -603,11 +603,15 @@ public final Insets getInsets(Insets insets) {
603603

604604

605605
private Graphics getBackingStoreGraphics(Graphics g) {
606-
Graphics bsg = backingStoreImage.getGraphics();
607-
bsg.setColor(g.getColor());
608-
bsg.setFont(g.getFont());
609-
bsg.setClip(g.getClipBounds());
610-
return bsg;
606+
if (!SwingUtilities2.isPrinting(g)) {
607+
Graphics bsg = backingStoreImage.getGraphics();
608+
bsg.setColor(g.getColor());
609+
bsg.setFont(g.getFont());
610+
bsg.setClip(g.getClipBounds());
611+
return bsg;
612+
} else {
613+
return g;
614+
}
611615
}
612616

613617

src/java.desktop/share/classes/sun/swing/SwingUtilities2.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1317,7 +1317,7 @@ public int hashCode() {
13171317
* returns true if the Graphics is print Graphics
13181318
* false otherwise
13191319
*/
1320-
static boolean isPrinting(Graphics g) {
1320+
public static boolean isPrinting(Graphics g) {
13211321
return (g instanceof PrinterGraphics || g instanceof PrintGraphics);
13221322
}
13231323

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
/*
2+
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
import java.awt.Component;
25+
import java.awt.Graphics;
26+
import java.awt.Graphics2D;
27+
import java.awt.print.PageFormat;
28+
import java.awt.print.Paper;
29+
import java.awt.print.Printable;
30+
import java.awt.print.PrinterException;
31+
import java.awt.print.PrinterJob;
32+
33+
import javax.swing.BoxLayout;
34+
import javax.swing.JFrame;
35+
import javax.swing.JPanel;
36+
import javax.swing.JScrollPane;
37+
import javax.swing.JTable;
38+
import javax.swing.JViewport;
39+
import javax.swing.SwingUtilities;
40+
import javax.swing.table.DefaultTableModel;
41+
42+
/*
43+
* @test
44+
* @key headful
45+
* @bug 8210807
46+
* @library /java/awt/regtesthelpers
47+
* @build PassFailJFrame
48+
* @summary Test to check if JTable can be printed when JScrollPane added to it.
49+
* @run main/manual JTableScrollPrintTest
50+
*/
51+
52+
public class JTableScrollPrintTest {
53+
public static JFrame frame;
54+
public static PassFailJFrame passFailJFrame;
55+
56+
public static void main(String[] args) throws Exception {
57+
SwingUtilities.invokeAndWait(() -> {
58+
try {
59+
initialize();
60+
} catch (Exception e) {
61+
throw new RuntimeException(e);
62+
}
63+
});
64+
passFailJFrame.awaitAndCheck();
65+
}
66+
67+
public static void initialize() throws Exception {
68+
final String INSTRUCTIONS = """
69+
Instructions to Test:
70+
1. Print table onto Paper/PDF, using the Print Dialog.
71+
2. If entire table is printed, then the Test is PASS.
72+
3. If table is partially printed without table cells,
73+
then the Test is FAIL.
74+
""";
75+
TestTable testTable = new TestTable(true);
76+
frame = new JFrame("JTable Print Test");
77+
passFailJFrame = new PassFailJFrame("Test Instructions", INSTRUCTIONS, 5L, 6, 35);
78+
79+
PassFailJFrame.addTestWindow(frame);
80+
PassFailJFrame.positionTestWindow(frame, PassFailJFrame.Position.VERTICAL);
81+
frame.add(testTable);
82+
frame.pack();
83+
frame.setVisible(true);
84+
PrintUtilities printerJob = new PrintUtilities(testTable);
85+
printerJob.print("Test BackingStore Image Print");
86+
}
87+
88+
public static class TestTable extends JPanel {
89+
public TestTable(Boolean useScrollPane) {
90+
91+
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
92+
93+
DefaultTableModel model = new DefaultTableModel();
94+
model.addColumn("Column 1");
95+
model.addColumn("Column 2");
96+
model.addColumn("Column 3");
97+
model.addColumn("Column 4");
98+
99+
for (int row = 1; row <= 5; row++) {
100+
model.addRow(new Object[]{
101+
"R" + row + " C1", "R" + row + " C2", "R" + row + " C3", "R" + row + " C4"});
102+
}
103+
104+
JTable table = new JTable(model);
105+
106+
if (useScrollPane == true) {
107+
JScrollPane sp = new JScrollPane(table,
108+
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
109+
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
110+
sp.getViewport().setScrollMode(JViewport.BACKINGSTORE_SCROLL_MODE);
111+
add(sp);
112+
} else {
113+
add(table.getTableHeader());
114+
add(table);
115+
}
116+
}
117+
}
118+
119+
static class PrintUtilities implements Printable {
120+
private Component componentToBePrinted;
121+
122+
public void printComponent(Component c, String jobname) {
123+
new PrintUtilities(c).print(jobname);
124+
}
125+
126+
public PrintUtilities(Component componentToBePrinted) {
127+
this.componentToBePrinted = componentToBePrinted;
128+
}
129+
130+
public void print(String jobname) {
131+
PrinterJob printJob = PrinterJob.getPrinterJob();
132+
PageFormat pf = printJob.defaultPage();
133+
pf.setOrientation(PageFormat.PORTRAIT);
134+
135+
// set margins to 1/2"
136+
Paper p = new Paper();
137+
p.setImageableArea(36, 36, p.getWidth() - 72, p.getHeight() - 72);
138+
pf.setPaper(p);
139+
140+
printJob.setPrintable(this, pf);
141+
printJob.setJobName(jobname);
142+
143+
if (printJob.printDialog()) {
144+
try {
145+
printJob.print();
146+
} catch (PrinterException pe) {
147+
System.out.println("Error printing: " + pe);
148+
}
149+
}
150+
}
151+
152+
public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
153+
if (pageIndex > 0) {
154+
return NO_SUCH_PAGE;
155+
} else {
156+
Graphics2D g2d = (Graphics2D)g;
157+
g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
158+
Component c = componentToBePrinted;
159+
c.setSize(c.getPreferredSize());
160+
161+
double panelX = c.getWidth();
162+
double panelY = c.getHeight();
163+
float imageableX = (float) pageFormat.getImageableWidth() - 1;
164+
float imageableY = (float) pageFormat.getImageableHeight() - 1;
165+
166+
double xscale = imageableX/panelX;
167+
double yscale = imageableY/panelY;
168+
double optimalScale;
169+
if (xscale < yscale) {
170+
optimalScale = xscale;
171+
} else {
172+
optimalScale = yscale;
173+
}
174+
175+
if (optimalScale > 1) {
176+
optimalScale = 1;
177+
}
178+
179+
g2d.scale(optimalScale, optimalScale);
180+
c.paint(g2d);
181+
return PAGE_EXISTS;
182+
}
183+
}
184+
}
185+
}

0 commit comments

Comments
 (0)