bug4697612.java revision 15235:fe58d505fffd
1/*
2 * Copyright (c) 2012, 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 * @key headful
27 * @bug 4697612 6244705
28 * @author Peter Zhelezniakov
29 * @library ../../regtesthelpers
30 * @build Util
31 * @run main bug4697612
32 */
33import java.io.*;
34import java.awt.*;
35import java.awt.event.*;
36import javax.swing.*;
37
38import javax.swing.text.BadLocationException;
39
40public class bug4697612 {
41
42    static final int FRAME_WIDTH = 300;
43    static final int FRAME_HEIGHT = 300;
44    static final int FONT_HEIGHT = 16;
45    private static volatile int frameHeight;
46    private static volatile int fontHeight;
47    private static JFrame frame;
48    private static JTextArea text;
49    private static JScrollPane scroller;
50
51    public static void main(String[] args) throws Throwable {
52        Robot robot = new Robot();
53        robot.setAutoDelay(100);
54
55        SwingUtilities.invokeAndWait(new Runnable() {
56
57            @Override
58            public void run() {
59                createAndShowGUI();
60            }
61        });
62
63        robot.waitForIdle();
64
65        SwingUtilities.invokeAndWait(new Runnable() {
66
67            @Override
68            public void run() {
69                text.requestFocus();
70            }
71        });
72
73        robot.waitForIdle();
74
75        // 4697612: pressing PgDn + PgUp should not alter caret position
76        Util.hitKeys(robot, KeyEvent.VK_HOME);
77        Util.hitKeys(robot, KeyEvent.VK_PAGE_DOWN);
78
79
80        int pos0 = getTextCaretPosition();
81        int caretHeight = getTextCaretHeight();
82        fontHeight = FONT_HEIGHT;
83
84        // iterate two times, for different (even and odd) font height
85        for (int i = 0; i < 2; i++) {
86
87            SwingUtilities.invokeAndWait(new Runnable() {
88
89                public void run() {
90                    text.setFont(text.getFont().deriveFont(fontHeight));
91                }
92            });
93
94            frameHeight = FRAME_HEIGHT;
95
96            for (int j = 0; j < caretHeight; j++) {
97                SwingUtilities.invokeAndWait(new Runnable() {
98
99                    public void run() {
100                        frame.setSize(FRAME_WIDTH, frameHeight);
101                    }
102                });
103
104                robot.waitForIdle();
105
106                Util.hitKeys(robot, KeyEvent.VK_PAGE_DOWN);
107                Util.hitKeys(robot, KeyEvent.VK_PAGE_UP);
108                robot.waitForIdle();
109
110                int pos = getTextCaretPosition();
111                if (pos0 != pos) {
112                    throw new RuntimeException("Failed 4697612: PgDn & PgUp keys scroll by different amounts");
113                }
114                frameHeight++;
115            }
116            fontHeight++;
117        }
118
119
120        // 6244705: pressing PgDn at the very bottom should not scroll
121        LookAndFeel laf = UIManager.getLookAndFeel();
122        if (laf.getID().equals("Aqua")) {
123            Util.hitKeys(robot, KeyEvent.VK_END);
124        } else {
125            Util.hitKeys(robot, KeyEvent.VK_CONTROL, KeyEvent.VK_END);
126        }
127
128        robot.waitForIdle();
129
130        pos0 = getScrollerViewPosition();
131        Util.hitKeys(robot, KeyEvent.VK_PAGE_DOWN);
132        robot.waitForIdle();
133
134        int pos = getScrollerViewPosition();
135
136        if (pos0 != pos) {
137            throw new RuntimeException("Failed 6244705: PgDn at the bottom causes scrolling");
138        }
139    }
140
141    private static int getTextCaretPosition() throws Exception {
142        final int[] result = new int[1];
143        SwingUtilities.invokeAndWait(new Runnable() {
144
145            @Override
146            public void run() {
147                result[0] = text.getCaretPosition();
148            }
149        });
150
151        return result[0];
152    }
153
154    private static int getTextCaretHeight() throws Exception {
155        final int[] result = new int[1];
156        SwingUtilities.invokeAndWait(new Runnable() {
157
158            @Override
159            public void run() {
160                try {
161                    int pos0 = text.getCaretPosition();
162                    Rectangle dotBounds = text.modelToView(pos0);
163                    result[0] = dotBounds.height;
164                } catch (BadLocationException ex) {
165                    throw new RuntimeException(ex);
166                }
167            }
168        });
169
170        return result[0];
171    }
172
173    private static int getScrollerViewPosition() throws Exception {
174        final int[] result = new int[1];
175        SwingUtilities.invokeAndWait(new Runnable() {
176
177            @Override
178            public void run() {
179                result[0] = scroller.getViewport().getViewPosition().y;
180            }
181        });
182
183        return result[0];
184    }
185
186    private static void createAndShowGUI() {
187        frame = new JFrame();
188        frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
189        frame.setPreferredSize(new Dimension(FRAME_WIDTH, FRAME_HEIGHT));
190        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
191
192        text = new JTextArea();
193        try {
194            InputStream is =
195                    bug4697612.class.getResourceAsStream("bug4697612.txt");
196            text.read(new InputStreamReader(is), null);
197        } catch (IOException e) {
198            throw new Error(e);
199        }
200
201        scroller = new JScrollPane(text);
202
203        frame.getContentPane().add(scroller);
204
205        frame.pack();
206        frame.setVisible(true);
207    }
208}
209