1 /* 2 * Copyright (c) 2008, 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 @key headful 27 @bug 6607170 28 @summary Tests for focus-auto-transfer. 29 @author Anton Tarasov: area=awt-focus 30 @library ../../regtesthelpers 31 @build Util 32 @run main ContainerFocusAutoTransferTest 33 */ 34 35 import java.applet.Applet; 36 import java.awt.AWTEvent; 37 import java.awt.Component; 38 import java.awt.ComponentOrientation; 39 import java.awt.DefaultKeyboardFocusManager; 40 import java.awt.KeyboardFocusManager; 41 import java.awt.Robot; 42 import java.awt.Color; 43 import java.awt.FlowLayout; 44 import java.awt.Toolkit; 45 import java.awt.event.AWTEventListener; 46 import java.awt.event.FocusEvent; 47 import java.awt.event.WindowEvent; 48 import javax.swing.JButton; 49 import javax.swing.JFrame; 50 import javax.swing.JPanel; 51 import test.java.awt.regtesthelpers.Util; 52 53 public class ContainerFocusAutoTransferTest extends Applet { 54 Robot robot; 55 TestFrame frame; 56 KeyboardFocusManager kfm; 57 enum TestCase { 58 REMOVAL { public String toString() { return "removal"; } }, 59 HIDING { public String toString() { return "hiding"; } }, 60 DISABLING { public String toString() { return "disabling"; } }, 61 DEFOCUSING { public String toString() { return "defocusing"; } }; 62 public abstract String toString(); 63 }; 64 65 public static void main(String[] args) { 66 ContainerFocusAutoTransferTest app = new ContainerFocusAutoTransferTest(); 67 app.init(); 68 app.start(); 69 } 70 71 public void init() { 72 robot = Util.createRobot(); 73 kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager(); 74 Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() { 75 public void eventDispatched(AWTEvent event) { 76 System.out.println("--> " + event); 77 } 78 }, FocusEvent.FOCUS_EVENT_MASK | WindowEvent.WINDOW_FOCUS_EVENT_MASK); 79 } 80 81 public void start() { 82 System.out.println("*** TEST #1 ***"); 83 test(TestCase.HIDING); 84 85 System.out.println("*** TEST #2 ***"); 86 test(TestCase.REMOVAL); 87 88 System.out.println("*** TEST #3 ***"); 89 test3(TestCase.DISABLING); 90 91 System.out.println("*** TEST #4 ***"); 92 test3(TestCase.DEFOCUSING); 93 94 System.out.println("*** TEST #5 ***"); 95 test4(); 96 97 System.out.println("Test passed."); 98 } 99 100 void test(final TestCase t) { 101 showFrame(); 102 test1(t); // Test for correct auto-transfer 103 test2(t); // Test for clearing focus 104 } 105 106 void test1(final TestCase t) { 107 Runnable action = new Runnable() { 108 public void run() { 109 KeyboardFocusManager.setCurrentKeyboardFocusManager(new TestKFM()); 110 if (t == TestCase.REMOVAL) { 111 frame.remove(frame.panel0); 112 113 } else if (t == TestCase.HIDING) { 114 frame.panel0.setVisible(false); 115 } 116 frame.repaint(); 117 } 118 }; 119 if (!Util.trackFocusGained(frame.b3, action, 2000, false)) { 120 throw new TestFailedException(t + ": focus wasn't transfered as expected!"); 121 } 122 KeyboardFocusManager.setCurrentKeyboardFocusManager(kfm); 123 } 124 125 void test2(TestCase t) { 126 frame.setFocusable(false); // exclude it from the focus cycle 127 if (t == TestCase.REMOVAL) { 128 frame.remove(frame.panel1); 129 130 } else if (t == TestCase.HIDING) { 131 frame.panel1.setVisible(false); 132 } 133 frame.repaint(); 134 Util.waitForIdle(robot); 135 if (kfm.getFocusOwner() != null) { 136 throw new TestFailedException(t + ": focus wasn't cleared!"); 137 } 138 } 139 140 void test3(final TestCase t) { 141 showFrame(); 142 Runnable action = new Runnable() { 143 public void run() { 144 if (t == TestCase.DISABLING) { 145 frame.b0.setEnabled(false); 146 147 } else if (t == TestCase.DEFOCUSING) { 148 frame.b0.setFocusable(false); 149 } 150 }}; 151 if (!Util.trackFocusGained(frame.b1, action, 2000, false)) { 152 throw new TestFailedException(t + ": focus wasn't transfered as expected!"); 153 } 154 } 155 156 void test4() { 157 showFrame(); 158 frame.setFocusableWindowState(false); 159 Util.waitForIdle(robot); 160 if (kfm.getFocusOwner() != null) { 161 throw new TestFailedException("defocusing the frame: focus wasn't cleared!"); 162 } 163 } 164 165 void showFrame() { 166 if (frame != null) { 167 frame.dispose(); 168 Util.waitForIdle(robot); 169 } 170 frame = new TestFrame(); 171 frame.setVisible(true); 172 Util.waitTillShown(frame); 173 174 if (!frame.b0.hasFocus()) { 175 Util.clickOnComp(frame.b0, robot); 176 Util.waitForIdle(robot); 177 if (!frame.b0.hasFocus()) { 178 throw new TestErrorException("couldn't set focus on " + frame.b2); 179 } 180 } 181 } 182 183 class TestKFM extends DefaultKeyboardFocusManager { 184 public boolean dispatchEvent(AWTEvent e) { 185 if (e.getID() == FocusEvent.FOCUS_GAINED) { 186 System.out.println(e); 187 Component src = (Component)e.getSource(); 188 if (src == frame.b1 || src == frame.b2) { 189 throw new TestFailedException("wrong focus transfer on removal!"); 190 } 191 } 192 return super.dispatchEvent(e); 193 } 194 } 195 } 196 197 class TestFrame extends JFrame { 198 public JPanel panel0 = new JPanel(); 199 public JPanel panel1 = new JPanel(); 200 public JButton b0 = new JButton("b0"); 201 public JButton b1 = new JButton("b1"); 202 public JButton b2 = new JButton("b2"); 203 public JButton b3 = new JButton("b3"); 204 public JButton b4 = new JButton("b4"); 205 206 public TestFrame() { 207 super("TestFrame"); 208 209 // The change of the orientation and the reverse order of 210 // adding the buttons to the panel is because in Container.removeNotify() 211 // the child components are removed in the reverse order. 212 // We want that the focus owner (b0) would be removed first and 213 // that the next traversable component would be b1. 214 panel0.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); 215 panel0.add(b2); 216 panel0.add(b1); 217 panel0.add(b0); 218 219 panel1.add(b3); 220 panel1.add(b4); 221 222 setLayout(new FlowLayout()); 223 add(panel0); 224 add(panel1); 225 pack(); 226 227 panel0.setBackground(Color.red); 228 panel1.setBackground(Color.blue); 229 } 230 } 231 232 // Thrown when the behavior being verified is found wrong. 233 class TestFailedException extends RuntimeException { 234 TestFailedException(String msg) { 235 super("Test failed: " + msg); 236 } 237 } 238 239 // Thrown when an error not related to the behavior being verified is encountered. 240 class TestErrorException extends RuntimeException { 241 TestErrorException(String msg) { 242 super("Unexpected error: " + msg); 243 } 244 }