Skip to content

Commit 67e52a3

Browse files
committed
8273634: [TEST_BUG] Improve javax/swing/text/ParagraphView/6364882/bug6364882.java
Reviewed-by: serb
1 parent b7425b6 commit 67e52a3

1 file changed

Lines changed: 239 additions & 0 deletions

File tree

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
/*
2+
* Copyright (c) 2006, 2021, 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.Dimension;
25+
import java.awt.Graphics;
26+
import java.awt.Rectangle;
27+
import java.awt.Shape;
28+
import java.awt.image.BufferedImage;
29+
import java.io.File;
30+
import java.io.IOException;
31+
import java.util.ArrayList;
32+
import java.util.Arrays;
33+
import java.util.List;
34+
import javax.imageio.ImageIO;
35+
import javax.swing.JEditorPane;
36+
import javax.swing.JFrame;
37+
import javax.swing.SwingUtilities;
38+
import javax.swing.text.AbstractDocument;
39+
import javax.swing.text.BadLocationException;
40+
import javax.swing.text.Position;
41+
import javax.swing.text.View;
42+
import javax.swing.text.html.HTMLEditorKit;
43+
44+
import static java.awt.image.BufferedImage.TYPE_INT_RGB;
45+
46+
/*
47+
* @test
48+
* @bug 6364882 8273634
49+
* @summary tests if broken and last lines in paragraph are not justified
50+
* @run main bug6364882
51+
*/
52+
public class bug6364882 {
53+
private static final String TEXT =
54+
"<html><body><p style=\"text-align: justify\">"
55+
+ "should be justified should be justified should be justified "
56+
+ "should be justified should be justified should be justified "
57+
+ "should be justified should be justified should be justified "
58+
+ "should be justified should be justified should be justified "
59+
+ "should be justified should be justified should be justified "
60+
+ "should be justified should be justified should be justified "
61+
+ "<br>"
62+
+ "should not be justified <br>"
63+
+ "should not be justified"
64+
+ "</body></html>";
65+
66+
private static final int WIDTH = 580;
67+
private static final int HEIGHT = 600;
68+
69+
public static final String IMAGE_FILENAME = "editorPane.png";
70+
71+
private static JEditorPane editorPane;
72+
73+
private static volatile List<Error> errors;
74+
75+
public static void main(String[] args) throws Exception {
76+
List<String> argList = Arrays.asList(args);
77+
// Show frame for visual inspection
78+
final boolean showFrame = argList.contains("-show");
79+
// Save the rendered image even if the test passes
80+
// If the test fails, the image is always saved
81+
final boolean saveImage = argList.contains("-save");
82+
83+
SwingUtilities.invokeAndWait(() -> {
84+
createUI(showFrame);
85+
86+
BufferedImage image = paintToImage();
87+
errors = checkJustification();
88+
89+
if (errors.size() > 0 || saveImage) {
90+
saveImage(image);
91+
dumpViews();
92+
}
93+
});
94+
95+
if (errors != null && errors.size() > 0) {
96+
String message = "Test failed: " + errors.size() + " error(s)";
97+
System.err.println(message);
98+
for (Error e : errors) {
99+
e.printStackTrace();
100+
}
101+
throw new RuntimeException(message + " - " + errors.get(0).getMessage());
102+
}
103+
104+
System.out.println("Test passed");
105+
}
106+
107+
private static void createUI(boolean showFrame) {
108+
editorPane = new JEditorPane();
109+
editorPane.setEditorKit(new HTMLEditorKit());
110+
((AbstractDocument) editorPane.getDocument()).setAsynchronousLoadPriority(-1);
111+
editorPane.setText(TEXT);
112+
113+
editorPane.setSize(WIDTH, HEIGHT);
114+
115+
if (showFrame) {
116+
JFrame frame = new JFrame("bug6364882");
117+
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
118+
119+
frame.getContentPane().add(editorPane);
120+
121+
frame.setSize(WIDTH, HEIGHT);
122+
frame.setLocationRelativeTo(null);
123+
frame.setVisible(true);
124+
}
125+
}
126+
127+
private static List<Error> checkJustification() {
128+
final List<Error> errors = new ArrayList<>(15);
129+
try {
130+
final View rootView = editorPane.getUI().getRootView(editorPane);
131+
final View blockView = rootView.getView(0);
132+
assert blockView.getViewCount() == 2
133+
: "blockView doesn't have 2 child views";
134+
final View bodyView = blockView.getView(1);
135+
final View paragraphView = bodyView.getView(0);
136+
// Expected to have 6 rows in the paragraph
137+
assert paragraphView.getViewCount() == 6
138+
: "paragraph doesn't have 6 rows of text";
139+
140+
final Rectangle bounds = editorPane.getBounds();
141+
142+
// Three rows should be justified
143+
final int oneX = getEndOfLineX(paragraphView.getView(0), bounds);
144+
if (oneX < bounds.width - 15) {
145+
errors.add(new Error("Text is not justified at line " + 0 + ": "
146+
+ oneX + " < " + (bounds.width - 15)));
147+
}
148+
for (int i = 1; i < 2; i++) {
149+
int lineX = getEndOfLineX(paragraphView.getView(i),
150+
bounds);
151+
if (oneX != lineX) {
152+
errors.add(new Error("Text is not justified at line " + i
153+
+ ": " + oneX + " != " + lineX));
154+
}
155+
}
156+
157+
// Fourth row should not be justified
158+
final int fourX = getEndOfLineX(paragraphView.getView(3), bounds);
159+
if (oneX == fourX) {
160+
errors.add(new Error("Fourth line is justified: "
161+
+ oneX + " vs " + fourX));
162+
}
163+
if (fourX > (bounds.width - bounds.width / 4)) {
164+
errors.add(new Error("Fourth line is justified: "
165+
+ fourX + " > "
166+
+ (bounds.width - bounds.width / 4)));
167+
}
168+
169+
// Fifth and sixth lines should not be justified
170+
final int fiveX = getEndOfLineX(paragraphView.getView(4), bounds);
171+
if (oneX == fiveX) {
172+
errors.add(new Error("Fifth line is justified: "
173+
+ oneX + "==" + fiveX));
174+
}
175+
if (fiveX > bounds.width / 2) {
176+
errors.add(new Error("Fifth line is justified: "
177+
+ fiveX + " > " + (bounds.width / 2)));
178+
}
179+
if (fiveX > fourX) {
180+
errors.add(new Error("Fifth line is justified: "
181+
+ fiveX + " > " + fourX));
182+
}
183+
final int sixX = getEndOfLineX(paragraphView.getView(5), bounds);
184+
if (fiveX != sixX) {
185+
errors.add(new Error("Fifth and sixth lines aren't of the "
186+
+ "same width: " + fiveX + " != " + sixX));
187+
}
188+
189+
return errors;
190+
} catch (BadLocationException e) {
191+
throw new RuntimeException(e);
192+
}
193+
}
194+
195+
private static int getEndOfLineX(final View rowView,
196+
final Rectangle bounds)
197+
throws BadLocationException {
198+
final View inlineView = rowView.getView(0);
199+
Shape loc = inlineView.modelToView(inlineView.getEndOffset() - 1,
200+
bounds,
201+
Position.Bias.Backward);
202+
return loc instanceof Rectangle
203+
? ((Rectangle) loc).x
204+
: loc.getBounds().x;
205+
}
206+
207+
private static BufferedImage paintToImage() {
208+
Dimension bounds = editorPane.getSize();
209+
BufferedImage im = new BufferedImage(bounds.width, bounds.height,
210+
TYPE_INT_RGB);
211+
Graphics g = im.getGraphics();
212+
editorPane.paint(g);
213+
g.dispose();
214+
return im;
215+
}
216+
217+
private static void saveImage(BufferedImage image) {
218+
try {
219+
ImageIO.write(image, "png", new File(IMAGE_FILENAME));
220+
} catch (IOException e) {
221+
throw new RuntimeException(e);
222+
}
223+
}
224+
225+
private static void dumpViews() {
226+
final View view = editorPane.getUI().getRootView(editorPane);
227+
dumpViews(view, "");
228+
}
229+
230+
private static void dumpViews(final View view, final String indent) {
231+
System.out.println(indent + view.getClass().getName() + ": "
232+
+ view.getStartOffset() + ", " + view.getEndOffset()
233+
+ "; span: " + view.getPreferredSpan(View.X_AXIS));
234+
final String nestedIndent = indent + " ";
235+
for (int i = 0; i < view.getViewCount(); i++) {
236+
dumpViews(view.getView(i), nestedIndent);
237+
}
238+
}
239+
}

0 commit comments

Comments
 (0)