/* * Copyright (c) 2001, 2023, 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 @summary unit test for ability of FocusTraversalPolicyProvider @key headful */ import java.awt.Button; import java.awt.Component; import java.awt.Container; import java.awt.ContainerOrderFocusTraversalPolicy; import java.awt.DefaultFocusTraversalPolicy; import java.awt.EventQueue; import java.awt.FocusTraversalPolicy; import java.awt.Frame; import java.awt.GridLayout; import java.awt.Panel; import java.awt.Robot; import java.awt.Window; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.LayoutFocusTraversalPolicy; public class FocusTraversalPolicyProviderTest { final String errorOrderMessage = "Test Failed. Traversal Order not correct."; final String successStage = "Test stage completed.Passed."; final int n_buttons = 4; final int jumps = 3 * n_buttons; Container[] cycle_roots = new Container[3]; Panel[] a_conts = new Panel[cycle_roots.length]; Panel[] b_conts = new Panel[cycle_roots.length]; Component[][] a_buttons = new Component[cycle_roots.length][n_buttons]; Component[][] b_buttons = new Component[cycle_roots.length][n_buttons]; static volatile Frame mainFrame = null; static volatile Frame frame = null; static volatile JFrame jframe = null; static Robot robot; public static void main(String[] args) throws Exception { FocusTraversalPolicyProviderTest test = new FocusTraversalPolicyProviderTest(); try { robot = new Robot(); EventQueue.invokeAndWait(test::init); robot.delay(1000); EventQueue.invokeAndWait(test::testStages); EventQueue.invokeAndWait(test::initSwingContInFrame); robot.delay(1000); EventQueue.invokeAndWait(test::testSwingContInFrame); // test for Swing container in java.awt.Frame System.out.println("Test passed."); } finally { EventQueue.invokeAndWait(() -> { if (mainFrame != null) mainFrame.dispose(); if (frame != null) frame.dispose(); if (jframe != null) jframe.dispose(); }); } } public void init() { mainFrame = new Frame("FocusTraversalPolicyProviderTest - main"); mainFrame.setSize(400, 400); mainFrame.setLocationRelativeTo(null); mainFrame.setVisible(true); for (int i = 0; i < cycle_roots.length; i++) { cycle_roots[i] = new Panel(); cycle_roots[i].setFocusable(false); cycle_roots[i].setName("root" + i); cycle_roots[i].setFocusCycleRoot(true); cycle_roots[i].setLayout (new GridLayout(1, 2)); mainFrame.add(cycle_roots[i]); a_conts[i] = new Panel(); a_conts[i].setName("ac" + i); a_conts[i].setFocusable(false); cycle_roots[i].add(a_conts[i]); b_conts[i] = new Panel(); b_conts[i].setName("bc" + i); b_conts[i].setFocusable(false); cycle_roots[i].add(b_conts[i]); for (int j = 0; j < n_buttons; j++){ String name = "a" + i + "x" + j; a_buttons[i][j] = new Button(name); a_buttons[i][j].setName(name); a_conts[i].add(a_buttons[i][j]); } for (int j = 0; j < n_buttons; j++){ String name = "b" + i + "x" + j; b_buttons[i][j] = new Button(name); b_buttons[i][j].setName(name); b_conts[i].add(b_buttons[i][j]); } } cycle_roots[0].setFocusTraversalPolicy(new DefaultFocusTraversalPolicy()); cycle_roots[1].setFocusTraversalPolicy(new ContainerOrderFocusTraversalPolicy()); cycle_roots[2].setFocusTraversalPolicy(new LayoutFocusTraversalPolicy()); } public void testStages() { for (int i = 0; i < cycle_roots.length; i++) { testStage(cycle_roots[i], a_conts[i], b_conts[i], a_buttons[i], b_buttons[i]); } } void testStage(Container aFCR, Container aCont, Container bCont, Component[] a_comps, Component[] b_comps) { System.out.println("focus cycle root = " + aFCR.getName()); System.out.println("policy = " + aFCR.getFocusTraversalPolicy()); System.out.println("aContainer = " + aCont.getName()); System.out.println("bContainer = " + bCont.getName()); System.out.println("Both containers are not Providers."); Component[] a_comps_backward = revertArray(a_comps); Component[] b_comps_backward = revertArray(b_comps); testForwardStage(aFCR, aCont, bCont, false, a_comps, false, b_comps); testBackwardStage(aFCR, aCont, bCont, false, a_comps_backward, false, b_comps_backward); System.out.println("Both containers are Providers."); testForwardStage(aFCR, aCont, bCont, true, a_comps, true, b_comps); testForwardStage(aFCR, aCont, bCont, true, shakeArray(a_comps), true, shakeArray(b_comps)); testBackwardStage(aFCR, aCont, bCont, true, a_comps_backward, true, b_comps_backward); testBackwardStage(aFCR, aCont, bCont, true, shakeArray(a_comps_backward), true, shakeArray(b_comps_backward)); System.out.println("aContainer.isProvider = true. " + "bContainer.isProvider = false."); testForwardStage(aFCR, aCont, bCont, true, a_comps, false, b_comps); testForwardStage(aFCR, aCont, bCont, true, shakeArray(a_comps), false, b_comps); testBackwardStage(aFCR, aCont, bCont, true, a_comps_backward, false, b_comps_backward); testBackwardStage(aFCR, aCont, bCont, true, shakeArray(a_comps_backward), false, b_comps_backward); System.out.println("aContainer.isProvider = false. " + "bContainer.isProvider = true."); testForwardStage(aFCR, aCont, bCont, false, a_comps, true, b_comps); testForwardStage(aFCR, aCont, bCont, false, a_comps, true, shakeArray(b_comps)); testBackwardStage(aFCR, aCont, bCont, false, a_comps_backward, true, b_comps_backward); testBackwardStage(aFCR, aCont, bCont, false, a_comps_backward, true, shakeArray(b_comps_backward)); System.out.println("Stage completed."); } public void printGoldOrder(Component[] comps) { String goldOrderStr = ""; for (int i =0;i < jumps; i++){ goldOrderStr += " " + comps[i].getName(); } System.out.println("GoldOrder: " + goldOrderStr); } public void testForwardStage(Container focusCycleRoot, Container aContainer, Container bContainer, boolean aProvider, Component[] aComps, boolean bProvider, Component[] bComps) { System.out.println("test forward traversal"); System.out.println("\taProvider = " + aProvider); System.out.println("\tbProvider = " + bProvider); Component[] goldOrder = new Component[2*aComps.length + bComps.length]; System.arraycopy(aComps, 0, goldOrder, 0, aComps.length); System.arraycopy(bComps, 0, goldOrder, aComps.length, bComps.length); System.arraycopy(aComps, 0, goldOrder, aComps.length + bComps.length, aComps.length); printGoldOrder(goldOrder); String jumpStr = ""; aContainer.setFocusTraversalPolicyProvider(aProvider); aContainer.setFocusTraversalPolicy( new ArrayOrderFocusTraversalPolicy(aContainer, aComps)); bContainer.setFocusTraversalPolicyProvider(bProvider); bContainer.setFocusTraversalPolicy( new ArrayOrderFocusTraversalPolicy(bContainer, bComps)); FocusTraversalPolicy policy = focusCycleRoot.getFocusTraversalPolicy(); System.out.println("policy=" + policy); Component current = policy.getFirstComponent(focusCycleRoot); for (int i = 0;i<jumps;i++){ jumpStr += " " + current.getName(); if (current != goldOrder[i]) { System.out.println("i=" + i + " label = "+ current.getName() + " i%8= " + i%goldOrder.length ); throw new RuntimeException(errorOrderMessage); } System.out.println("getComponentAfter() on " + focusCycleRoot + ", " + current); current = policy.getComponentAfter(focusCycleRoot, current); System.out.println("RealOrder :" + jumpStr); } System.out.println(successStage); } public void testBackwardStage(Container focusCycleRoot, Container aContainer, Container bContainer, boolean aProvider, Component[] aComps, boolean bProvider, Component[] bComps) { System.out.println("test backward traversal"); System.out.println("\taProvider = " + aProvider); System.out.println("\tbProvider = " + bProvider); Component[] goldOrder = new Component[2*bComps.length + bComps.length]; System.arraycopy(bComps, 0, goldOrder, 0, bComps.length); System.arraycopy(aComps, 0, goldOrder, bComps.length, aComps.length); System.arraycopy(bComps, 0, goldOrder, aComps.length + bComps.length, bComps.length); printGoldOrder(goldOrder); String jumpStr = ""; aContainer.setFocusTraversalPolicyProvider(aProvider); aContainer.setFocusTraversalPolicy( new ArrayOrderFocusTraversalPolicy(aContainer, revertArray(aComps))); bContainer.setFocusTraversalPolicyProvider(bProvider); bContainer.setFocusTraversalPolicy( new ArrayOrderFocusTraversalPolicy(bContainer, revertArray(bComps))); FocusTraversalPolicy policy = focusCycleRoot.getFocusTraversalPolicy(); System.out.println("policy=" + policy); Component current = policy.getLastComponent(focusCycleRoot); for (int i = 0;i<jumps;i++){ jumpStr += " " + current.getName(); if (current != goldOrder[i]) { System.out.println("i=" + i + " label = "+ current.getName()); throw new RuntimeException(errorOrderMessage); } System.out.println("getComponentBefore() on " + focusCycleRoot.getName() + ", " + current.getName()); current = policy.getComponentBefore(focusCycleRoot, current); System.out.println("RealOrder :" + jumpStr); } System.out.println(successStage); } Component[] shakeArray(Component[] comps) { Component[] new_comps = new Component[comps.length]; System.arraycopy(comps, 0, new_comps, 0, comps.length); new_comps[0] = comps[1]; new_comps[1] = comps[0]; return new_comps; } Component[] revertArray(Component[] comps) { Component[] new_comps = new Component[comps.length]; for (int i=0; i < comps.length; i++) { new_comps[i] = comps[comps.length - 1 - i]; } return new_comps; } public void initSwingContInFrame() { System.out.println("test Swing policy provider in AWT Frame."); jframe = new JFrame("FocusTraversalPolicyProviderTest - JFrame"); jframe.setName("JFrame"); JPanel panel1 = createPanel(); jframe.getContentPane().add(panel1); frame = new Frame("FocusTraversalPolicyProviderTest - Frame"); frame.setName("Frame"); JPanel panel2 = createPanel(); panel2.setFocusTraversalPolicyProvider(true); panel2.setFocusTraversalPolicy(jframe.getFocusTraversalPolicy()); frame.add(panel2); jframe.pack(); jframe.setVisible(true); frame.pack(); frame.setVisible(true); } public void testSwingContInFrame() { FocusTraversalPolicy policy = frame.getFocusTraversalPolicy(); FocusTraversalPolicy jpolicy = jframe.getFocusTraversalPolicy(); System.out.println("policy = " + policy); System.out.println("jpolicy = " + jpolicy); assertEquals("Different default components.", jpolicy.getDefaultComponent(jframe), policy.getDefaultComponent(frame)); assertEquals("Different first components.", jpolicy.getFirstComponent(jframe), policy.getFirstComponent(frame)); assertEquals("Different last components.", jpolicy.getLastComponent(jframe), policy.getLastComponent(frame)); System.out.println("test forward traversal order."); Component jcur = jpolicy.getFirstComponent(jframe); Component cur = jpolicy.getFirstComponent(frame); for (int i = 0; i < 2 * n_buttons; i++) { assertEquals("Wrong sequence (step=" + i + ")", jcur, cur); jcur = jpolicy.getComponentAfter(jframe, jcur); cur = policy.getComponentAfter(frame, cur); } System.out.println("test backward traversal order."); jcur = jpolicy.getLastComponent(jframe); cur = jpolicy.getLastComponent(frame); for (int i = 0; i < 2 * n_buttons; i++) { assertEquals("Wrong sequence (step=" + i + ")", jcur, cur); jcur = jpolicy.getComponentBefore(jframe, jcur); cur = policy.getComponentBefore(frame, cur); } } public void assertEquals(String msg, Component expected, Component actual) { if (expected == null && actual != null || actual == null && expected != null) { throw new RuntimeException(msg + "(expected=" + expected + ", actual=" + actual + ")"); } String expected_name = expected.getName(); String actual_name = actual.getName(); if ((expected_name != null && !expected_name.equals(actual_name)) || (actual_name != null && !actual_name.equals(expected_name))) { throw new RuntimeException(msg + "(expected_name=" + expected_name + ", actual_name=" + actual_name + ")"); } } public JPanel createPanel() { JPanel pane = new JPanel(); pane.setName("jpanel"); for (int i = 0; i < n_buttons; i++) { JButton btn = new JButton("jbtn" + i); btn.setName("jbtn" + i); pane.add(btn); } return pane; } } class ArrayOrderFocusTraversalPolicy extends FocusTraversalPolicy { final Component[] comps; final Container cont; public ArrayOrderFocusTraversalPolicy(Container aCont, Component[] aComps) { if (aCont == null) { throw new NullPointerException("aCont is null."); } cont = aCont; comps = new Component[aComps.length]; for (int i = 0; i < comps.length; i++) { comps[i] = aComps[i]; } } private void checkContainer(Container aCont) { if (aCont != cont) { System.err.println("aCont = " + aCont); System.err.println("cont = " + cont); throw new IllegalArgumentException( "Policy is not registered for this container."); } } private int findIndex(Component aComp) { for (int i = 0; i < comps.length; i++) { if (aComp == comps[i]) { return i; } } return -1; } public Component getComponentAfter(Container focusCycleRoot, Component aComponent) { checkContainer(focusCycleRoot); int current_index = findIndex(aComponent); if (current_index < 0) { return null; } current_index++; if (current_index < comps.length) { return comps[current_index]; } if (focusCycleRoot.isFocusCycleRoot()) { return getFirstComponent(focusCycleRoot); } else { return null; } } public Component getComponentBefore(Container focusCycleRoot, Component aComponent) { checkContainer(focusCycleRoot); int current_index = findIndex(aComponent); if (current_index < 0) { return null; } current_index--; if (current_index >= 0) { return comps[current_index]; } if (focusCycleRoot.isFocusCycleRoot()) { return getLastComponent(focusCycleRoot); } else { return null; } } public Component getFirstComponent(Container focusCycleRoot) { checkContainer(focusCycleRoot); return comps[0]; } public Component getLastComponent(Container focusCycleRoot) { checkContainer(focusCycleRoot); return comps[comps.length - 1]; } public Component getDefaultComponent(Container focusCycleRoot) { return getFirstComponent(focusCycleRoot); } public Component getInitialComponent(Window window) { throw new UnsupportedOperationException("getInitialComponent() is not supported."); } public Component[] getCycle(Container focusCycleRoot) { checkContainer(focusCycleRoot); Component[] temp = new Component[comps.length]; System.arraycopy(comps, 0, temp, 0, comps.length); return temp; } }