From a70eddca0d35789e7774b1aa221ef00b2c1c7e43 Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy Date: Fri, 27 Jan 2012 17:00:16 +0400 Subject: [PATCH] 7109962: [macosx] closed/javax/swing/JList/6462008/bug6462008.java fails on MacOS Reviewed-by: rupashka --- .../javax/swing/JList/6462008/bug6462008.java | 415 ++++++++++++++++++ 1 file changed, 415 insertions(+) create mode 100644 jdk/test/javax/swing/JList/6462008/bug6462008.java diff --git a/jdk/test/javax/swing/JList/6462008/bug6462008.java b/jdk/test/javax/swing/JList/6462008/bug6462008.java new file mode 100644 index 00000000000..9e009cc0369 --- /dev/null +++ b/jdk/test/javax/swing/JList/6462008/bug6462008.java @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2011, 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 6462008 + * @summary Tests that mouse/keyboard work properly on JList with lead < 0 or > list.getModel().getSize() + * @author Shannon Hickey + * @run main bug6462008 + */ +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import java.util.*; +import sun.awt.SunToolkit; + +public class bug6462008 { + + private static final int DONT_CARE = -2; + private static int anchorLead; + private static boolean isAquaLAF; + private static int controlKey; + private static JList list; + private static SunToolkit toolkit; + private static Robot robot; + + public static void main(String[] args) throws Exception { + toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + robot = new Robot(); + robot.setAutoDelay(100); + + isAquaLAF = "Aqua".equals(UIManager.getLookAndFeel().getID()); + controlKey = isAquaLAF ? KeyEvent.VK_META : KeyEvent.VK_CONTROL; + + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + createAndShowGUI(); + } + }); + + toolkit.realSync(); + + setAnchorLead(-1); + toolkit.realSync(); + + testListSelection(); + + setAnchorLead(100); + toolkit.realSync(); + + testListSelection(); + } + + public static void testListSelection() throws Exception { + + // Space + robot.keyPress(KeyEvent.VK_SPACE); + robot.keyRelease(KeyEvent.VK_SPACE); + + toolkit.realSync(); + checkSelection(); + resetList(); + toolkit.realSync(); + + // Control + Space + robot.keyPress(KeyEvent.VK_CONTROL); + robot.keyPress(KeyEvent.VK_SPACE); + robot.keyRelease(KeyEvent.VK_SPACE); + robot.keyRelease(KeyEvent.VK_CONTROL); + + toolkit.realSync(); + checkSelection(); + resetList(); + toolkit.realSync(); + + // Shift + Space + robot.keyPress(KeyEvent.VK_SHIFT); + robot.keyPress(KeyEvent.VK_SPACE); + robot.keyRelease(KeyEvent.VK_SPACE); + robot.keyRelease(KeyEvent.VK_SHIFT); + + toolkit.realSync(); + checkSelection(); + resetList(); + toolkit.realSync(); + + // Control + Shift + Space + robot.keyPress(KeyEvent.VK_CONTROL); + robot.keyPress(KeyEvent.VK_SHIFT); + robot.keyPress(KeyEvent.VK_SPACE); + robot.keyRelease(KeyEvent.VK_SPACE); + robot.keyRelease(KeyEvent.VK_SHIFT); + robot.keyRelease(KeyEvent.VK_CONTROL); + + toolkit.realSync(); + checkSelection(); + resetList(); + toolkit.realSync(); + + + // Control + A Multiple Selection + + robot.keyPress(controlKey); + robot.keyPress(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_A); + robot.keyRelease(controlKey); + + toolkit.realSync(); + checkSelectionAL(-1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9); + resetList(); + setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + toolkit.realSync(); + + // Control + A Single Selection + robot.keyPress(controlKey); + robot.keyPress(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_A); + robot.keyRelease(controlKey); + + toolkit.realSync(); + checkSelectionAL(0, 0, 0); + resetList(); + setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + setSelectionInterval(5, 5); + toolkit.realSync(); + + + // Control + A Selection interval (5, 5) + robot.keyPress(controlKey); + robot.keyPress(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_A); + robot.keyRelease(controlKey); + + toolkit.realSync(); + checkSelection(5); + resetList(); + toolkit.realSync(); + + // Page Down + // Not applicable for the Aqua L&F + if (!isAquaLAF) { + robot.keyPress(KeyEvent.VK_PAGE_DOWN); + robot.keyRelease(KeyEvent.VK_PAGE_DOWN); + + toolkit.realSync(); + checkSelection(9, 9, 9); + resetList(); + toolkit.realSync(); + } + + // Shift + Page Down + /* + * We really want to use robot here, but there seems to be a bug in AWT's + * robot implementation (see 6463168). For now, we'll invoke the action + * directly instead. When the bug is fixed, we'll use the following four + * lines instead: + * robot.keyPress(KeyEvent.VK_SHIFT); + * robot.keyPress(KeyEvent.VK_PAGE_DOWN); + * robot.keyRelease(KeyEvent.VK_PAGE_DOWN); + * robot.keyRelease(KeyEvent.VK_SHIFT); + */ + + scrollDownExtendSelection(); + + toolkit.realSync(); + checkSelection(0, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9); + resetList(); + toolkit.realSync(); + + // Down + robot.keyPress(KeyEvent.VK_DOWN); + robot.keyRelease(KeyEvent.VK_DOWN); + + toolkit.realSync(); + checkSelectionAL(0, 0, 0); + resetList(); + toolkit.realSync(); + + // L + robot.keyPress(KeyEvent.VK_L); + robot.keyRelease(KeyEvent.VK_L); + + toolkit.realSync(); + checkSelectionAL(0, 0, 0); + resetList(); + toolkit.realSync(); + + // Click item 4 + Point p = clickItem4(); + robot.mouseMove(p.x, p.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + + + toolkit.realSync(); + checkSelectionAL(4, 4, 4); + resetList(); + toolkit.realSync(); + + + // Control + Click item 4 + robot.keyPress(controlKey); + p = clickItem4(); + robot.mouseMove(p.x, p.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.keyRelease(controlKey); + + + toolkit.realSync(); + checkSelectionAL(4, 4, 4); + resetList(); + toolkit.realSync(); + + // Shift + Click item 4 + robot.keyPress(KeyEvent.VK_SHIFT); + p = clickItem4(); + robot.mouseMove(p.x, p.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.keyRelease(KeyEvent.VK_SHIFT); + + + toolkit.realSync(); + checkSelectionAL(0, 4, 0, 1, 2, 3, 4); + resetList(); + toolkit.realSync(); + + + // Control + Shift + Click item 4 + robot.keyPress(controlKey); + robot.keyPress(KeyEvent.VK_SHIFT); + p = clickItem4(); + robot.mouseMove(p.x, p.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.keyRelease(KeyEvent.VK_SHIFT); + robot.keyRelease(controlKey); + + toolkit.realSync(); + checkSelectionAL(0, 4); + resetList(); + toolkit.realSync(); + } + + private static DefaultListModel getModel() { + DefaultListModel listModel = new DefaultListModel(); + for (int i = 0; i < 10; i++) { + listModel.addElement("List Item " + i); + } + return listModel; + } + + private static Point clickItem4() throws Exception { + + final Point[] result = new Point[1]; + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + Rectangle r = list.getCellBounds(4, 4); + Point p = new Point(r.x + r.width / 2, r.y + r.height / 2); + SwingUtilities.convertPointToScreen(p, list); + result[0] = p; + } + }); + + return result[0]; + } + + private static void resetList() throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + list.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + list.getSelectionModel().clearSelection(); + setAnchorLeadNonThreadSafe(); + } + }); + } + + private static void scrollDownExtendSelection() throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + list.getActionMap().get("scrollDownExtendSelection"). + actionPerformed(new ActionEvent(list, + ActionEvent.ACTION_PERFORMED, null)); + } + }); + } + + private static void setSelectionMode(final int selectionMode) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + list.getSelectionModel().setSelectionMode(selectionMode); + setAnchorLeadNonThreadSafe(); + } + }); + } + + private static void setSelectionInterval(final int index0, final int index1) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + list.getSelectionModel().setSelectionInterval(index0, index1); + setAnchorLeadNonThreadSafe(); + } + }); + } + + private static void setAnchorLead(final int anchorLeadValue) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + anchorLead = anchorLeadValue; + setAnchorLeadNonThreadSafe(); + } + }); + } + + private static void setAnchorLeadNonThreadSafe() { + list.getSelectionModel().setAnchorSelectionIndex(anchorLead); + ((DefaultListSelectionModel) list.getSelectionModel()).moveLeadSelectionIndex(anchorLead); + } + + private static void createAndShowGUI() { + JFrame frame = new JFrame("bug6462008"); + frame.setSize(200, 500); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + list = new JList(getModel()); + JPanel panel = new JPanel(new BorderLayout()); + panel.add(list); + frame.getContentPane().add(panel); + + frame.setVisible(true); + } + + private static void checkSelection(int... sels) throws Exception { + checkSelectionAL(DONT_CARE, DONT_CARE, sels); + } + + private static void checkSelectionAL(final int anchor, final int lead, final int... sels) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + checkSelectionNonThreadSafe(anchor, lead, sels); + } + }); + } + + private static void checkSelectionNonThreadSafe(int anchor, int lead, int... sels) { + ListSelectionModel lsm = list.getSelectionModel(); + + int actualAnchor = lsm.getAnchorSelectionIndex(); + int actualLead = lsm.getLeadSelectionIndex(); + + if (anchor != DONT_CARE && actualAnchor != anchor) { + throw new RuntimeException("anchor is " + actualAnchor + ", should be " + anchor); + } + + if (lead != DONT_CARE && actualLead != lead) { + throw new RuntimeException("lead is " + actualLead + ", should be " + lead); + } + + Arrays.sort(sels); + boolean[] checks = new boolean[list.getModel().getSize()]; + for (int i : sels) { + checks[i] = true; + } + + int index0 = Math.min(lsm.getMinSelectionIndex(), 0); + int index1 = Math.max(lsm.getMaxSelectionIndex(), list.getModel().getSize() - 1); + + for (int i = index0; i <= index1; i++) { + if (lsm.isSelectedIndex(i)) { + if (i < 0 || i >= list.getModel().getSize() || !checks[i]) { + throw new RuntimeException(i + " is selected when it should not be"); + } + } else if (i >= 0 && i < list.getModel().getSize() && checks[i]) { + throw new RuntimeException(i + " is supposed to be selected"); + } + } + } +}