1 /* 2 * Copyright (c) 2011, 2017, 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 25 /** 26 * @test 27 * @key headful 28 * @bug 6427244 8144240 8166003 8169879 29 * @summary Test that pressing HOME correctly moves caret in I18N document. 30 * @author Sergey Groznyh 31 * @library ../../../regtesthelpers 32 * @build JRobot 33 * @run main bug6427244 34 */ 35 36 import java.awt.Container; 37 import java.awt.Dimension; 38 import java.awt.Point; 39 import java.awt.Shape; 40 import java.awt.event.KeyEvent; 41 import javax.swing.JComponent; 42 import javax.swing.JFrame; 43 import javax.swing.JTextPane; 44 import javax.swing.SwingUtilities; 45 import javax.swing.text.Position; 46 47 public class bug6427244 { 48 private static final JRobot ROBOT = JRobot.getRobot(); 49 50 final static int TP_SIZE = 200; 51 final static String[] SPACES = new String[] { 52 "\u0020", // ASCII space 53 "\u2002", // EN space 54 "\u2003", // EM space 55 "\u2004", // THREE-PER-EM space 56 "\u2005", // ... etc. 57 "\u2006", 58 //"\u2007", 59 "\u2008", 60 "\u2009", 61 "\u200a", 62 "\u200b", 63 "\u205f", 64 "\u3000", 65 }; 66 final static String[] WORDS = new String[] { 67 "It", "is", "a", "long", "paragraph", "for", "testing", "GlyphPainter2\n\n", 68 }; 69 70 public static void main(String[] args) { 71 bug6427244 t = new bug6427244(); 72 for (String space: SPACES) { 73 t.init(space); 74 t.testCaretPosition(); 75 } 76 77 System.out.println("OK"); 78 // Dispose the test interface upon completion 79 t.destroyTestInterface(); 80 } 81 82 void init(final String space) { 83 try { 84 SwingUtilities.invokeAndWait(new Runnable() { 85 public void run() { 86 String text = null; 87 for (String word: WORDS) { 88 if (text == null) { 89 text = ""; 90 } else { 91 text += space; 92 } 93 text += word; 94 } 95 tp = new JTextPane(); 96 tp.setText(text + 97 "Some arabic: \u062a\u0641\u0627\u062d and some not."); 98 if (jf == null) { 99 jf = new JFrame(); 100 jf.setTitle("bug6427244"); 101 jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 102 jf.setSize(TP_SIZE, TP_SIZE); 103 jf.setVisible(true); 104 } 105 Container c = jf.getContentPane(); 106 c.removeAll(); 107 c.add(tp); 108 c.invalidate(); 109 c.validate(); 110 dim = c.getSize(); 111 } 112 }); 113 blockTillDisplayed(tp); 114 ROBOT.waitForIdle(); 115 } catch (Exception ex) { 116 throw new RuntimeException(ex); 117 } 118 } 119 120 void destroyTestInterface() { 121 try { 122 SwingUtilities.invokeAndWait(new Runnable() { 123 @Override 124 public void run() { 125 // Dispose the frame 126 jf.dispose(); 127 } 128 }); 129 } catch (Exception ex) { 130 // No-op 131 } 132 } 133 134 void blockTillDisplayed(JComponent comp) throws Exception { 135 while (comp != null && isCompVisible == false) { 136 try { 137 SwingUtilities.invokeAndWait(new Runnable() { 138 @Override 139 public void run() { 140 isCompVisible = comp.isVisible(); 141 } 142 }); 143 144 if (isCompVisible == false) { 145 // A short wait for component to be visible 146 Thread.sleep(1000); 147 } 148 } catch (InterruptedException ex) { 149 // No-op. Thread resumed from sleep 150 } catch (Exception ex) { 151 throw new RuntimeException(ex); 152 } 153 } 154 } 155 156 public void testCaretPosition() { 157 final Point p[] = new Point[1]; 158 try { 159 SwingUtilities.invokeAndWait(new Runnable() { 160 public void run() { 161 p[0] = tp.getLocationOnScreen(); 162 163 // the right-top corner position 164 p[0].x += (dim.width - 5); 165 p[0].y += 5; 166 } 167 }); 168 } catch (Exception ex) { 169 throw new RuntimeException(ex); 170 } 171 ROBOT.mouseMove(p[0].x, p[0].y); 172 ROBOT.clickMouse(); 173 ROBOT.hitKey(KeyEvent.VK_HOME); 174 ROBOT.waitForIdle(); 175 // this will fail if caret moves out of the 1st line. 176 if (getCaretOrdinate() != 0) { 177 // Dispose the test interface upon completion 178 destroyTestInterface(); 179 throw new RuntimeException("Test Failed."); 180 } 181 } 182 183 int getCaretOrdinate() { 184 final int[] y = new int[1]; 185 try { 186 SwingUtilities.invokeAndWait(new Runnable() { 187 public void run() { 188 Shape s; 189 try { 190 s = tp.getUI().getRootView(tp).modelToView( 191 tp.getCaretPosition(), tp.getBounds(), 192 Position.Bias.Forward); 193 } catch (Exception e) { 194 throw new RuntimeException(e); 195 } 196 y[0] = s.getBounds().y; 197 } 198 }); 199 } catch (Exception e) { 200 throw new RuntimeException(e); 201 } 202 return y[0]; 203 } 204 205 private JFrame jf; 206 private JTextPane tp; 207 private Dimension dim; 208 private volatile boolean isCompVisible = false; 209 }