提交 40bf42d9 编写于 作者: P psadhukhan

8214702: Wrong text position for whitespaced string in printing Swing text

Summary: Do not use justification if string width of text is within screenWidth
Reviewed-by: prr, serb
Contributed-by: verghese@amazon.com
上级 58c0e728
/*
* Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2019, 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
......@@ -511,11 +511,15 @@ public class SwingUtilities2 {
String trimmedText = trimTrailingSpaces(text);
if (!trimmedText.isEmpty()) {
float screenWidth = (float) g2d.getFont().getStringBounds
(trimmedText, DEFAULT_FRC).getWidth();
(trimmedText, getFontRenderContext(c)).getWidth();
TextLayout layout = createTextLayout(c, text, g2d.getFont(),
g2d.getFontRenderContext());
layout = layout.getJustifiedLayout(screenWidth);
// If text fits the screenWidth, then do not need to justify
if (SwingUtilities2.stringWidth(c, g2d.getFontMetrics(),
trimmedText) > screenWidth) {
layout = layout.getJustifiedLayout(screenWidth);
}
/* Use alternate print color if specified */
Color col = g2d.getColor();
if (col instanceof PrintColorUIResource) {
......@@ -640,8 +644,12 @@ public class SwingUtilities2 {
g2d.getFontRenderContext());
if (isPrinting) {
float screenWidth = (float)g2d.getFont().
getStringBounds(text, DEFAULT_FRC).getWidth();
layout = layout.getJustifiedLayout(screenWidth);
getStringBounds(text, getFontRenderContext(c)).getWidth();
// If text fits the screenWidth, then do not need to justify
if (SwingUtilities2.stringWidth(c, g2d.getFontMetrics(),
text) > screenWidth) {
layout = layout.getJustifiedLayout(screenWidth);
}
}
TextHitInfo leading =
TextHitInfo.leading(underlinedIndex);
......@@ -804,7 +812,11 @@ public class SwingUtilities2 {
if (!trimmedText.isEmpty()) {
float screenWidth = (float)g2d.getFont().
getStringBounds(trimmedText, frc).getWidth();
layout = layout.getJustifiedLayout(screenWidth);
// If text fits the screenWidth, then do not need to justify
if (SwingUtilities2.stringWidth(c, g2d.getFontMetrics(),
trimmedText) > screenWidth) {
layout = layout.getJustifiedLayout(screenWidth);
}
/* Use alternate print color if specified */
Color col = g2d.getColor();
......
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2019, 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
......@@ -48,7 +48,7 @@ import javax.swing.UnsupportedLookAndFeelException;
public class bug8033069NoScrollBar implements Runnable {
private static final String[] NO_SCROLL_ITEMS = new String[] {
"A", "B", "C", "D", "E", "F"
"AA", "B", "C", "D", "E", "F"
};
private final Robot robot;
......@@ -110,6 +110,7 @@ public class bug8033069NoScrollBar implements Runnable {
// Move mouse pointer to the center of the fist combo box
Point p = cb1.getLocationOnScreen();
Dimension d = cb1.getSize();
System.out.println(d.width + "," + d.height);
robot.mouseMove(p.x + d.width / 2, p.y + d.height / 2);
// Click it to open popup
robot.mousePress(InputEvent.BUTTON1_MASK);
......
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2019, 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
......@@ -36,7 +36,7 @@ import java.awt.AWTException;
public class bug8033069ScrollBar extends bug8033069NoScrollBar {
private static final String[] SCROLL_ITEMS = new String[] {
"A", "B", "C", "D", "E", "F",
"AA", "B", "C", "D", "E", "F",
"G", "H", "I", "J", "K", "L",
"M", "N", "O", "P", "Q", "R"
};
......
/*
* Copyright (c) 2019, 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.
*/
/* @test
@bug 8214702
@summary Verifies text position for whitespaced string in printing Swing text
@run main/manual TestTextPosInPrint
*/
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Font;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.print.Printable;
import java.awt.print.PageFormat;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.WindowConstants;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
public class TestTextPosInPrint implements Printable {
private static final CountDownLatch testEndedSignal = new CountDownLatch(1);
private static final int testTimeout = 300000;
private static volatile String testFailureMsg;
private static volatile boolean testPassed;
private static volatile boolean testFinished;
private static PrinterJob job;
private static JPanel panel;
private static JFrame f;
public static void main(String[] args) throws Exception {
job = PrinterJob.getPrinterJob();
if (job.getPrintService() == null) {
System.out.println("This test requires printers to be installed. Exiting.");
return;
}
SwingUtilities.invokeLater(() -> createAndShowTestDialog());
try {
if (!testEndedSignal.await(testTimeout, TimeUnit.MILLISECONDS)) {
throw new RuntimeException(String.format(
"Test timeout '%d ms' elapsed.", testTimeout));
}
if (!testPassed) {
String failureMsg = testFailureMsg;
if ((failureMsg != null) && (!failureMsg.trim().isEmpty())) {
throw new RuntimeException(failureMsg);
} else {
throw new RuntimeException("Test failed.");
}
}
} catch (InterruptedException ie) {
throw new RuntimeException(ie);
} finally {
testFinished = true;
SwingUtilities.invokeAndWait(() -> f.dispose());
}
}
private static void doTest() throws Exception {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
f = new JFrame();
f.setLocationRelativeTo(null);
panel = new JPanel();
panel.setLayout(new BorderLayout());
Font font = new Font("Serif", Font.PLAIN, 12);
JLabel l1 = new JLabel(" 1. ABCDE");
l1.setHorizontalAlignment(SwingConstants.LEFT);
JLabel l2 = new JLabel(" 2. ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ");
l2.setHorizontalAlignment(SwingConstants.LEFT);
//JLabel l3 = new JLabel(" 3. ABCDE ");
JLabel l3 = new JLabel(" 3. ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ");
l3.setHorizontalAlignment(SwingConstants.LEFT);
panel.add(BorderLayout.NORTH, l1);
panel.add(BorderLayout.CENTER, l2);
panel.add(BorderLayout.SOUTH, l3);
f.getContentPane().add(BorderLayout.NORTH, panel);
f.setSize(400, 300);
f.setVisible(true);
job.setPrintable(new TestTextPosInPrint());
if (job.printDialog()) {
try {
job.print();
} catch (PrinterException pe) {
throw new RuntimeException(pe);
}
}
}
private static void pass() {
testPassed = true;
testEndedSignal.countDown();
}
private static void fail(String failureMsg) {
testFailureMsg = failureMsg;
testPassed = false;
testEndedSignal.countDown();
}
private static String convertMillisToTimeStr(int millis) {
if (millis < 0) {
return "00:00:00";
}
int hours = millis / 3600000;
int minutes = (millis - hours * 3600000) / 60000;
int seconds = (millis - hours * 3600000 - minutes * 60000) / 1000;
return String.format("%02d:%02d:%02d", hours, minutes, seconds);
}
private static void createAndShowTestDialog() {
String description =
" 1. Click on \"Start Test\" button.\r\n" +
" 2. Multiple strings will be displayed on console.\r\n" +
" 3. A print dialog will be shown. Select any printer to print. " +
"\r\n" +
" If the printed output of the strings are same without any alignment issue, click on \"PASS\"\r\n" +
" button, otherwise click on \"FAIL\" button.";
final JDialog dialog = new JDialog();
dialog.setTitle("SaveFileWithoutPrinter");
dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
dialog.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
dialog.dispose();
fail("Main dialog was closed.");
}
});
final JLabel testTimeoutLabel = new JLabel(String.format(
"Test timeout: %s", convertMillisToTimeStr(testTimeout)));
final long startTime = System.currentTimeMillis();
final Timer timer = new Timer(0, null);
timer.setDelay(1000);
timer.addActionListener((e) -> {
int leftTime = testTimeout - (int) (System.currentTimeMillis() - startTime);
if ((leftTime < 0) || testFinished) {
timer.stop();
dialog.dispose();
}
testTimeoutLabel.setText(String.format(
"Test timeout: %s", convertMillisToTimeStr(leftTime)));
});
timer.start();
JTextArea textArea = new JTextArea(description);
textArea.setEditable(false);
final JButton testButton = new JButton("Start Test");
final JButton passButton = new JButton("PASS");
final JButton failButton = new JButton("FAIL");
testButton.addActionListener((e) -> {
testButton.setEnabled(false);
new Thread(() -> {
try {
doTest();
SwingUtilities.invokeLater(() -> {
passButton.setEnabled(true);
failButton.setEnabled(true);
});
} catch (Throwable t) {
t.printStackTrace();
dialog.dispose();
fail("Exception occurred in a thread executing the test.");
}
}).start();
});
passButton.setEnabled(false);
passButton.addActionListener((e) -> {
dialog.dispose();
pass();
});
failButton.setEnabled(false);
failButton.addActionListener((e) -> {
dialog.dispose();
fail("Printed texts are not aligned as shown in console");
});
JPanel mainPanel = new JPanel(new BorderLayout());
JPanel labelPanel = new JPanel(new FlowLayout());
labelPanel.add(testTimeoutLabel);
mainPanel.add(labelPanel, BorderLayout.NORTH);
mainPanel.add(textArea, BorderLayout.CENTER);
JPanel buttonPanel = new JPanel(new FlowLayout());
buttonPanel.add(testButton);
buttonPanel.add(passButton);
buttonPanel.add(failButton);
mainPanel.add(buttonPanel, BorderLayout.SOUTH);
dialog.add(mainPanel);
dialog.pack();
dialog.setVisible(true);
}
@Override
public int print(Graphics pg, PageFormat pf, int pageNum)
throws PrinterException {
if (pageNum > 0){
return Printable.NO_SUCH_PAGE;
}
Graphics2D g2 = (Graphics2D) pg;
g2.translate(pf.getImageableX(), pf.getImageableY());
panel.paint(g2);
return Printable.PAGE_EXISTS;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册