b372f28ad4
Reviewed-by: prr
510 lines
19 KiB
Java
510 lines
19 KiB
Java
/*
|
|
* 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;
|
|
}
|
|
}
|