1 /* 2 * Copyright (c) 2020, 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 8223788 28 * @summary JSpinner buttons in JColorChooser dialog may capture focus 29 * using TAB Key 30 * @run main JSpinnerButtonFocusTest 31 */ 32 33 import java.awt.Robot; 34 import java.awt.BorderLayout; 35 import java.awt.ContainerOrderFocusTraversalPolicy; 36 import java.awt.event.FocusAdapter; 37 import java.awt.event.FocusEvent; 38 import java.awt.event.KeyEvent; 39 import java.util.concurrent.CountDownLatch; 40 import java.util.concurrent.TimeUnit; 41 import javax.swing.JFrame; 42 import javax.swing.JSpinner; 43 import javax.swing.JSpinner.DefaultEditor; 44 import javax.swing.SwingUtilities; 45 import javax.swing.UIManager; 46 47 public class JSpinnerButtonFocusTest { 48 static JFrame frame; 49 static Robot robot; 50 static JSpinner spinner1, spinner2; 51 static DefaultEditor editor1, editor2; 52 static volatile boolean isJTextFieldFocused; 53 static volatile CountDownLatch latch1; 54 main(String args[])55 public static void main(String args[]) throws Exception { 56 57 for (UIManager.LookAndFeelInfo LF : 58 UIManager.getInstalledLookAndFeels()) { 59 latch1 = new CountDownLatch(1); 60 try { 61 UIManager.setLookAndFeel(LF.getClassName()); 62 robot = new Robot(); 63 robot.setAutoDelay(50); 64 65 SwingUtilities.invokeAndWait(() -> { 66 frame = new JFrame(); 67 spinner1 = new JSpinner(); 68 spinner2 = new JSpinner(); 69 70 frame.setLayout(new BorderLayout()); 71 frame.getContentPane().add(spinner1, BorderLayout.NORTH); 72 frame.getContentPane().add(spinner2, BorderLayout.SOUTH); 73 74 editor1 = ((DefaultEditor)spinner1.getEditor()); 75 editor1.setFocusable(false); 76 spinner1.setFocusable(false); 77 78 editor2 = (DefaultEditor) spinner2.getEditor(); 79 editor2.setFocusable(false); 80 spinner2.setFocusable(false); 81 82 frame.setFocusTraversalPolicy( 83 new ContainerOrderFocusTraversalPolicy()); 84 frame.setFocusTraversalPolicyProvider(true); 85 86 frame.setAlwaysOnTop(true); 87 frame.pack(); 88 frame.setVisible(true); 89 }); 90 robot.waitForIdle(); 91 92 editor1.getTextField().addFocusListener(new FocusAdapter() { 93 @Override 94 public void focusGained(FocusEvent e) { 95 super.focusGained(e); 96 robot.keyPress(KeyEvent.VK_TAB); 97 robot.keyRelease(KeyEvent.VK_TAB); 98 latch1.countDown(); 99 } 100 }); 101 102 SwingUtilities.invokeAndWait(() -> { 103 editor1.getTextField().requestFocusInWindow(); 104 }); 105 106 if (!latch1.await(15, TimeUnit.MINUTES)) { 107 throw new RuntimeException(LF.getClassName() + 108 ": Timeout waiting for editor1 to gain focus."); 109 } 110 111 robot.waitForIdle(); 112 SwingUtilities.invokeAndWait(() -> { 113 isJTextFieldFocused = editor2.getTextField().isFocusOwner(); 114 }); 115 116 if (!isJTextFieldFocused) { 117 throw new RuntimeException(LF.getClassName() + 118 ": Spinner's Text Field doesn't have focus "); 119 } 120 } finally { 121 if (frame != null) { 122 SwingUtilities.invokeAndWait(frame::dispose); 123 } 124 } 125 } 126 } 127 } 128