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