Path: blob/master/test/jdk/javax/swing/JList/4618767/JListSelectedElementTest.java
66646 views
/*1* Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.awt.Robot;24import java.awt.event.FocusAdapter;25import java.awt.event.FocusEvent;26import java.awt.event.KeyEvent;27import java.util.Arrays;28import java.util.List;29import java.util.concurrent.CountDownLatch;30import java.util.concurrent.TimeUnit;31import java.util.concurrent.atomic.AtomicBoolean;32import java.util.concurrent.atomic.AtomicReference;33import java.util.stream.Collectors;34import javax.swing.JFrame;35import javax.swing.JList;36import javax.swing.JMenu;37import javax.swing.JMenuBar;38import javax.swing.JMenuItem;39import javax.swing.SwingUtilities;40import javax.swing.UIManager;41import javax.swing.UIManager.LookAndFeelInfo;42import javax.swing.UnsupportedLookAndFeelException;43import javax.swing.event.MenuEvent;44import javax.swing.event.MenuListener;454647import static javax.swing.UIManager.getInstalledLookAndFeels;4849/*50* @test51* @key headful52* @bug 461876753* @summary This test confirms that typing a letter while a JList has focus now makes the selection54* not jump to the item whose text starts with that letter if that typed letter is accompanied55* by modifier keys such as ALT or CTRL(eg: ALT+F).56* @run main JListSelectedElementTest57*/58public class JListSelectedElementTest {5960private static final int FILE_MENU = KeyEvent.VK_F;61private static JFrame frame;62private static JList<String> list;63private static Robot robot;64private static CountDownLatch listGainedFocusLatch;65private static CountDownLatch menuSelectedEventLatch;6667public static void main(String[] args) throws Exception {68runTest();69}7071public static void runTest() throws Exception {72robot = new Robot();73robot.setAutoWaitForIdle(true);74robot.setAutoDelay(200);7576final boolean isMac = System.getProperty("os.name")77.toLowerCase()78.contains("os x");7980List<String> lafs = Arrays.stream(getInstalledLookAndFeels())81.map(LookAndFeelInfo::getClassName)82.collect(Collectors.toList());83for (final String laf : lafs) {84listGainedFocusLatch = new CountDownLatch(1);85menuSelectedEventLatch = new CountDownLatch(1);86try {87AtomicBoolean lafSetSuccess = new AtomicBoolean(false);88SwingUtilities.invokeAndWait(() -> {89lafSetSuccess.set(setLookAndFeel(laf));90if (lafSetSuccess.get()) {91createUI();92}93});94if (!lafSetSuccess.get()) {95continue;96}97robot.waitForIdle();9899// Wait until the list gains focus.100if (!listGainedFocusLatch.await(3, TimeUnit.SECONDS)) {101throw new RuntimeException("Waited too long, but can't gain focus for list");102}103104// Select element named as 'bill'105hitKeys(KeyEvent.VK_B);106107// Assertion check to verify that the selected node is 'bill'108AtomicReference<String> elementSel = new AtomicReference<>();109SwingUtilities.invokeAndWait(() -> elementSel.set(list.getSelectedValue()));110final String elementSelBefore = elementSel.get();111if (!"bill".equals(elementSelBefore)) {112throw new RuntimeException("Test failed for " + laf113+ " as the list element selected: " + elementSel114+ " is not the expected one 'bill'"115);116}117118// Now operate Menu using Mnemonics, different key combinations for different OSes.119// For most OSes it's ALT+F; on macOS it's ALT+CNTRL+F except for Nimbus LaF.120if (isMac && !laf.contains("Nimbus")) {121hitKeys(KeyEvent.VK_ALT, KeyEvent.VK_CONTROL, FILE_MENU);122} else {123hitKeys(KeyEvent.VK_ALT, FILE_MENU);124}125126// Wait until the menu got selected.127if (!menuSelectedEventLatch.await(3, TimeUnit.SECONDS)) {128throw new RuntimeException("Waited too long, but can't select menu using mnemonics for " + laf);129}130131hitKeys(KeyEvent.VK_ENTER);132133AtomicReference<String> elementSelAfter = new AtomicReference<>();134SwingUtilities.invokeAndWait(() -> elementSelAfter.set(list.getSelectedValue()));135136// As per the fix of BugID 4618767, the list element selection should not change137if (!elementSelBefore.equals(elementSelAfter.get())) {138throw new RuntimeException("Test failed for " + laf139+ " as list.getSelectedValue() before = " + elementSel140+ " not equal to list.getSelectedValue() after pressing Enter = " + elementSelAfter141);142}143System.out.println("Test passed for laf: " + laf);144145} finally {146SwingUtilities.invokeAndWait(JListSelectedElementTest::disposeFrame);147}148}149}150151private static void hitKeys(int... keys) {152for (int key : keys) {153robot.keyPress(key);154}155156for (int i = keys.length - 1; i >= 0; i--) {157robot.keyRelease(keys[i]);158}159}160161private static void createUI() {162frame = new JFrame();163list = new JList<>(new String[]{"anaheim", "bill", "chicago", "dingo", "ernie", "freak"});164list.addFocusListener(new FocusAdapter() {165@Override166public void focusGained(FocusEvent e) {167listGainedFocusLatch.countDown();168}169});170JMenu menu = new JMenu("File");171menu.setMnemonic(FILE_MENU);172JMenuItem menuItem = new JMenuItem("Dummy");173menu.add(menuItem);174menu.addMenuListener(new MenuListener() {175@Override176public void menuSelected(MenuEvent e) {177menuSelectedEventLatch.countDown();178}179180@Override181public void menuDeselected(MenuEvent e) {182}183184@Override185public void menuCanceled(MenuEvent e) {186}187});188189JMenuBar menuBar = new JMenuBar();190menuBar.add(menu);191192frame.setJMenuBar(menuBar);193frame.setContentPane(list);194frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);195frame.pack();196frame.setAlwaysOnTop(true);197frame.setLocationRelativeTo(null);198frame.setVisible(true);199}200201private static boolean setLookAndFeel(String lafName) {202try {203UIManager.setLookAndFeel(lafName);204} catch (UnsupportedLookAndFeelException ignored) {205System.out.println("Ignoring Unsupported L&F: " + lafName);206return false;207} catch (ClassNotFoundException | InstantiationException208| IllegalAccessException e) {209throw new RuntimeException(e);210}211return true;212}213214private static void disposeFrame() {215if (frame != null) {216frame.dispose();217frame = null;218}219}220221}222223224