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