1 /* 2 * Copyright (c) 2013, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* 27 test 28 @bug 8023392 29 @summary Swing text components printed with spaces between chars 30 @author Anton Nashatyrev 31 @run applet/manual=yesno bug8023392.html 32 */ 33 34 import javax.swing.*; 35 import javax.swing.border.LineBorder; 36 import java.applet.Applet; 37 import java.awt.*; 38 import java.awt.event.ActionEvent; 39 import java.awt.event.ActionListener; 40 import java.awt.font.TextAttribute; 41 import java.awt.print.PageFormat; 42 import java.awt.print.Printable; 43 import java.awt.print.PrinterException; 44 import java.awt.print.PrinterJob; 45 import java.text.AttributedCharacterIterator; 46 import java.text.AttributedString; 47 48 49 public class bug8023392 extends Applet { 50 static final String[] instructions = { 51 "A Frame containing several pairs of labels ((a) and (b)) is displayed.", 52 "Labels of each pair look the same and are left-aligned (with spaces ", 53 "between chars).", 54 "1. Hit the print button.", 55 "2. Select any available printer (printing to file is also fine).", 56 "3. Look at the printing result (paper, PDF, PS, etc.):", 57 " The (a) and (b) labels should look almost the same and the (a) labels", 58 " shouldn't appear as if they are stretched along X axis."}; 59 60 public void init() { 61 this.setLayout(new BorderLayout()); 62 add(new SimplePrint2(), BorderLayout.CENTER); 63 64 Sysout.createDialogWithInstructions(instructions); 65 66 } 67 68 public static class SimplePrint2 extends JPanel 69 implements ActionListener, Printable { 70 JLabel label1; 71 JLabel label2; 72 JButton printButton; 73 74 75 public SimplePrint2() { 76 setLayout(new BorderLayout()); 77 label1 = new JLabel("2a) a b c d e" + 78 " "); 79 label2 = new JLabel("2b) a b c d e"); 80 81 Box p1 = new Box(BoxLayout.Y_AXIS); 82 p1.add(label1); 83 p1.add(label2); 84 p1.add(new JLabel("wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww") { 85 String s = "3a) a b c d e "; 86 @Override 87 protected void paintComponent(Graphics g) { 88 sun.swing.SwingUtilities2.drawChars(this, g, s.toCharArray(), 89 0, s.length(), 0, 15); 90 } 91 }); 92 p1.add(new JLabel("wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww") { 93 String s = "3b) a b c d e"; 94 @Override 95 protected void paintComponent(Graphics g) { 96 sun.swing.SwingUtilities2.drawChars(this, g, s.toCharArray(), 97 0, s.length(), 0, 15); 98 } 99 }); 100 p1.add(new JLabel("wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww") { 101 String s = "4a) a b c d e "; 102 AttributedCharacterIterator it; 103 { 104 AttributedString as = new AttributedString(s); 105 as.addAttribute(TextAttribute.FONT, getFont()); 106 as.addAttribute(TextAttribute.FOREGROUND, Color.RED, 3, 8); 107 it = as.getIterator(); 108 } 109 @Override 110 protected void paintComponent(Graphics g) { 111 sun.swing.SwingUtilities2.drawString(this, g, it, 0, 15); 112 } 113 }); 114 115 p1.add(new JLabel("wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww") { 116 String s = "4b) a b c d e"; 117 AttributedCharacterIterator it; 118 { 119 AttributedString as = new AttributedString(s); 120 as.addAttribute(TextAttribute.FONT, getFont()); 121 as.addAttribute(TextAttribute.FOREGROUND, Color.RED, 3, 8); 122 it = as.getIterator(); 123 } 124 @Override 125 protected void paintComponent(Graphics g) { 126 sun.swing.SwingUtilities2.drawString(this, g, it, 0, 15); 127 } 128 }); 129 130 JPanel p2 = new JPanel(); 131 printButton = new JButton("Print"); 132 printButton.addActionListener(this); 133 p2.add(printButton); 134 135 Container c = this; 136 c.add(p1, BorderLayout.CENTER); 137 c.add(p2, BorderLayout.SOUTH); 138 139 String[] data = { 140 "1a) \u30aa\u30f3\u30e9\u30a4\u30f3\u6d88\u8fbc" + 141 " ", 142 "1b) \u30aa\u30f3\u30e9\u30a4\u30f3\u6d88\u8fbc" 143 }; 144 JList l0 = new JList(data); 145 l0.setVisibleRowCount(l0.getModel().getSize()); 146 JScrollPane jsp = new JScrollPane(l0); 147 l0.setBorder(new LineBorder(Color.GRAY)); 148 c.add(jsp, BorderLayout.NORTH); 149 150 for (Component comp : new Component[]{label1, label2, printButton}) { 151 comp.setFont(new Font("Monospaced", 0, 16)); 152 } 153 } 154 155 public void actionPerformed(ActionEvent e) { 156 PrinterJob job = PrinterJob.getPrinterJob(); 157 job.setPrintable(this); 158 if (job.printDialog()) { 159 try { 160 job.print(); 161 } catch (PrinterException ex) { 162 ex.printStackTrace(); 163 } 164 } 165 } 166 167 public int print(Graphics graphics, 168 PageFormat pageFormat, 169 int pageIndex) 170 throws PrinterException { 171 if (pageIndex >= 1) { 172 return Printable.NO_SUCH_PAGE; 173 } 174 175 this.paint(graphics); 176 return Printable.PAGE_EXISTS; 177 } 178 } 179 } 180 181 182 /** 183 * ************************************************* 184 * Standard Test Machinery 185 * DO NOT modify anything below -- it's a standard 186 * chunk of code whose purpose is to make user 187 * interaction uniform, and thereby make it simpler 188 * to read and understand someone else's test. 189 * ************************************************** 190 */ 191 class Sysout { 192 private static TestDialog dialog; 193 194 public static void createDialogWithInstructions(String[] instructions) { 195 dialog = new TestDialog(new Frame(), "Instructions"); 196 dialog.printInstructions(instructions); 197 dialog.show(); 198 println("Any messages for the tester will display here."); 199 } 200 201 public static void createDialog() { 202 dialog = new TestDialog(new Frame(), "Instructions"); 203 String[] defInstr = {"Instructions will appear here. ", ""}; 204 dialog.printInstructions(defInstr); 205 dialog.show(); 206 println("Any messages for the tester will display here."); 207 } 208 209 210 public static void printInstructions(String[] instructions) { 211 dialog.printInstructions(instructions); 212 } 213 214 215 public static void println(String messageIn) { 216 dialog.displayMessage(messageIn); 217 } 218 219 }// Sysout class 220 221 222 class TestDialog extends Dialog { 223 224 TextArea instructionsText; 225 TextArea messageText; 226 int maxStringLength = 80; 227 228 //DO NOT call this directly, go through Sysout 229 public TestDialog(Frame frame, String name) { 230 super(frame, name); 231 int scrollBoth = TextArea.SCROLLBARS_BOTH; 232 instructionsText = new TextArea("", 15, maxStringLength, scrollBoth); 233 add("North", instructionsText); 234 235 messageText = new TextArea("", 5, maxStringLength, scrollBoth); 236 add("South", messageText); 237 238 pack(); 239 240 show(); 241 }// TestDialog() 242 243 //DO NOT call this directly, go through Sysout 244 public void printInstructions(String[] instructions) { 245 //Clear out any current instructions 246 instructionsText.setText(""); 247 248 //Go down array of instruction strings 249 250 String printStr, remainingStr; 251 for (int i = 0; i < instructions.length; i++) { 252 //chop up each into pieces maxSringLength long 253 remainingStr = instructions[i]; 254 while (remainingStr.length() > 0) { 255 //if longer than max then chop off first max chars to print 256 if (remainingStr.length() >= maxStringLength) { 257 //Try to chop on a word boundary 258 int posOfSpace = remainingStr. 259 lastIndexOf(' ', maxStringLength - 1); 260 261 if (posOfSpace <= 0) posOfSpace = maxStringLength - 1; 262 263 printStr = remainingStr.substring(0, posOfSpace + 1); 264 remainingStr = remainingStr.substring(posOfSpace + 1); 265 } 266 //else just print 267 else { 268 printStr = remainingStr; 269 remainingStr = ""; 270 } 271 272 instructionsText.append(printStr + "\n"); 273 274 }// while 275 276 }// for 277 278 }//printInstructions() 279 280 //DO NOT call this directly, go through Sysout 281 public void displayMessage(String messageIn) { 282 messageText.append(messageIn + "\n"); 283 } 284 285 }// TestDialog class 286