1 /*
   2  * Copyright (c) 2007, 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       6463545
  28   @summary   Tests javax.swing.LayoutFocusTraversalPolicy functionality.
  29   @author    anton.tarasov, oleg.sukhodolsky: area=awt.focus
  30   @library   ../../regtesthelpers
  31   @build     AbstractPolicyTest
  32   @run       main LayoutFTPTest
  33 */
  34 
  35 import java.awt.*;
  36 import javax.swing.*;
  37 import java.awt.event.*;
  38 import java.util.*;
  39 import test.java.awt.regtesthelpers.AbstractPolicyTest;
  40 
  41 /*
  42 
  43 Below are some notes about changes in SortingFocusTraversalPolicy behaviour.
  44 
  45 container(root) [...]           - focus traversal cycle with the <container> as the root.
  46 container(provider) [...]       - focus traversal cycle with the <container> as the provider.
  47 container(..)(focusable) [...]  - <container> is implicitly set focusable.
  48 comp[unfocusable]               - <comp> is set unfocusable.
  49 
  50 
  51 1. frame [ container(root)(focusable) [...] ]
  52 
  53 - getComponentAfter(<frame>, <container>) returns <container>.
  54 
  55   If <container> is the default component to focus in its own cycle.  * NO CHANGE *
  56 
  57 
  58 3. frame [ comp1 container(root)(focusable) [ comp2 ] comp3 ]
  59 
  60 - getComponentBefore(<frame>, <comp3>) returns <comp2>.                                 ** BEHAVIOUR CHANGE **
  61 
  62   Previously <container> would be returned. This was a bug as it
  63   wasn't according to the spec.
  64 
  65 - getComponentBefore(<container>, <comp2>) returns <container>.     * NO CHANGE *
  66 
  67 - getComponentBefore(<frame>, <container>) returns <comp1>.         * NO CHANGE *
  68 
  69 - getComponentBefore(<container>, <container>) returns <comp2>.     * NO CHANGE *
  70 
  71 
  72 4. frame [ container(provider) [...] comp ]
  73 
  74 - getComponentAfter(<frame>, <container>) returns <container>'s default.                ** BEHAVIOUR CHANGE. SPEC ADDITION **
  75 
  76   Previously <comp> would be returned. Not specified in the spec.
  77 
  78 - getComponentBefore(<frame>, <comp>) returns <container>'s last.                       ** SPEC CHANGE **
  79 
  80   The spec says (incorrectly) that default should be returned.
  81 
  82 
  83 5. frame [ container(provider)(focusable) [...] comp2 ]
  84 
  85 - getComponentBefore(<frame>, <comp2>) returns <container>'s last.                      ** BEHAVIOUR CHANGE. SPEC ADDITION **
  86 
  87   Previously <container> would be returned. Not specified in the spec.
  88 
  89 
  90 6. frame [ comp1 container(root) [...] comp2 ]
  91 
  92 - getComponentAfter(<frame>, <comp1>) returns <container>'s default.                    ** BEHAVIOUR CHANGE. SPEC ADDITION **
  93 
  94   Previously <comp2> would be returned. It's just the fix for 6240842.
  95   Not specified in the spec.
  96 
  97 
  98 7. frame [ comp1 container(root) [...] comp2(unfocusable) comp3 ]
  99 
 100 - getComponentBefore(<frame>, <comp3>) returns <container>'s default.                   ** BEHAVIOUR CHANGE **
 101 
 102   Previously <comp1> would be returned. This was a bug, because
 103   in case if <comp2> is focusable getComponentBefore(<frame>, <comp2>) would
 104   return <container>'s default.
 105 
 106 */
 107 
 108 public class LayoutFTPTest {
 109     final int TESTS_NUMBER = 11;
 110 
 111     public static void main(String[] args) {
 112         LayoutFTPTest app = new LayoutFTPTest();
 113         app.start();
 114     }
 115 
 116     public void start() {
 117         try {
 118             Class clazz = null;
 119             AbstractPolicyTest test = null;
 120 
 121             for (int i = 1; i <= TESTS_NUMBER; i++) {
 122                 clazz = Class.forName("PolicyTest" + i);
 123                 if (clazz != null) {
 124                     test = (AbstractPolicyTest)clazz.newInstance();
 125                     System.out.print("Test " + i + " is in progress...");
 126                     test.testIt();
 127                     System.out.println(" passed.");
 128                 }
 129             }
 130         } catch (RuntimeException rte) {
 131             throw rte;
 132         } catch (Exception e) {
 133             throw new RuntimeException("Error: unexpected exception cought!", e);
 134         }
 135     }
 136 }
 137 
 138 /*
 139  * frame [ container1 [...] container2 [...] container3 [...] ]
 140  * - verifies simple configuration.
 141  */
 142 class PolicyTest1 extends AbstractPolicyTest {
 143     protected Frame createFrame() {
 144         JFrame jframe = (JFrame) registerComponent("jframe", new JFrame("Test Frame"));
 145         jframe.setLayout(new GridLayout(3, 1));
 146 
 147         for (int i = 0; i < 3; i++) {
 148             Container cont = (Container) registerComponent("jpanel" + i, new JPanel());
 149             for (int j = 0; j < 3; j++) {
 150                 cont.add(registerComponent("btn " + (j + i*100), new JButton("jbutton")));
 151             }
 152             jframe.add(cont);
 153         }
 154         return jframe;
 155     }
 156 
 157     protected void customizeHierarchy() {
 158         ((Container)getComponent("jframe")).setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
 159     }
 160 
 161     protected Map<String, String> getForwardOrder() {
 162         Map<String, String> order = new HashMap<String, String>();
 163         order.put("btn 0", "btn 1");
 164         order.put("btn 1", "btn 2");
 165         order.put("btn 2", "btn 100");
 166         order.put("btn 100", "btn 101");
 167         order.put("btn 101", "btn 102");
 168         order.put("btn 102", "btn 200");
 169         order.put("btn 200", "btn 201");
 170         order.put("btn 201", "btn 202");
 171         order.put("btn 202", "btn 0");
 172         order.put("jpanel0", "btn 0");
 173         order.put("jpanel1", "btn 100");
 174         order.put("jpanel2", "btn 200");
 175         order.put("jframe", "btn 0");
 176         return order;
 177     }
 178 
 179     protected Map<String, String> getBackwardOrder() {
 180         Map<String, String> order = new HashMap<String, String>();
 181         order.put("btn 0", "btn 202");
 182         order.put("btn 1", "btn 0");
 183         order.put("btn 2", "btn 1");
 184         order.put("btn 100", "btn 2");
 185         order.put("btn 101", "btn 100");
 186         order.put("btn 102", "btn 101");
 187         order.put("btn 200", "btn 102");
 188         order.put("btn 201", "btn 200");
 189         order.put("btn 202", "btn 201");
 190         order.put("jpanel0", "btn 202");
 191         order.put("jpanel1", "btn 2");
 192         order.put("jpanel2", "btn 102");
 193         order.put("jframe", "btn 202");
 194         return order;
 195     }
 196 
 197     protected String[] getContainersToTest() {
 198         return new String[] {"jframe"};
 199     }
 200 
 201     protected String getDefaultComp(String focusCycleRoot_id) {
 202         return "btn 0";
 203     }
 204 
 205     protected String getFirstComp(String focusCycleRoot_id) {
 206         return "btn 0";
 207     }
 208 
 209     protected String getLastComp(String focusCycleRoot_id) {
 210         return "btn 202";
 211     }
 212 }
 213 
 214 /*
 215  * frame [ comp container(provider) [...] comp ]
 216  * - transfering focus through a provider.
 217  */
 218 class PolicyTest2 extends AbstractPolicyTest {
 219 
 220     protected Frame createFrame() {
 221         JFrame jframe = (JFrame) registerComponent("jframe", new JFrame("Test Frame"));
 222         jframe.setLayout(new FlowLayout());
 223 
 224         jframe.add(registerComponent("btn 1", new JButton("jbutton")));
 225 
 226         Container cont = (Container)registerComponent("jpanel", new JPanel());
 227         cont.add(registerComponent("btn 2", new JButton("jbutton")));
 228         cont.add(registerComponent("btn 3", new JButton("jbutton")));
 229         jframe.add(cont);
 230 
 231         jframe.add(registerComponent("btn 4", new JButton("jbutton")));
 232 
 233         return jframe;
 234     }
 235 
 236     protected void customizeHierarchy() {
 237         ((Container)getComponent("jframe")).setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
 238         ((Container)getComponent("jpanel")).setFocusTraversalPolicyProvider(true);
 239     }
 240 
 241     protected Map<String, String> getForwardOrder() {
 242         Map<String, String> order = new HashMap<String, String>();
 243         order.put("jframe", "btn 1");
 244         order.put("btn 1", "btn 2");
 245         order.put("btn 2", "btn 3");
 246         order.put("btn 3", "btn 4");
 247         order.put("btn 4", "btn 1");
 248         order.put("jpanel", "btn 2");
 249         return order;
 250     }
 251 
 252     protected Map<String, String> getBackwardOrder() {
 253         Map<String, String> order = new HashMap<String, String>();
 254         order.put("btn 4", "btn 3");
 255         order.put("btn 3", "btn 2");
 256         order.put("btn 2", "btn 1");
 257         order.put("btn 1", "btn 4");
 258         return order;
 259     }
 260 
 261     protected String[] getContainersToTest() {
 262         return new String[] {"jframe", "jpanel"};
 263     }
 264 
 265     protected String getDefaultComp(String focusCycleRoot_id) {
 266         if ("jframe".equals(focusCycleRoot_id)) {
 267             return "btn 1";
 268         } else if ("jpanel".equals(focusCycleRoot_id)) {
 269             return "btn 2";
 270         }
 271         return null;
 272     }
 273 
 274     protected String getFirstComp(String focusCycleRoot_id) {
 275         return getDefaultComp(focusCycleRoot_id);
 276     }
 277 
 278     protected String getLastComp(String focusCycleRoot_id) {
 279         if ("jframe".equals(focusCycleRoot_id)) {
 280             return "btn 4";
 281         } else if ("jpanel".equals(focusCycleRoot_id)) {
 282             return "btn 3";
 283         }
 284         return null;
 285     }
 286 }
 287 
 288 /*
 289  * frame [ comp container(root) [...] comp ]
 290  * - transfering focus through a root (includes the case reported in the CR 6240842).
 291  */
 292 class PolicyTest3 extends AbstractPolicyTest {
 293 
 294     protected Frame createFrame() {
 295         JFrame jframe = (JFrame) registerComponent("jframe", new JFrame("Test Frame"));
 296         jframe.setLayout(new FlowLayout());
 297 
 298         jframe.add(registerComponent("btn 1", new JButton("jbutton")));
 299 
 300         Container cont = (Container)registerComponent("jpanel", new JPanel());
 301         cont.add(registerComponent("btn 2", new JButton("jbutton")));
 302         cont.add(registerComponent("btn 3", new JButton("jbutton")));
 303         jframe.add(cont);
 304 
 305         jframe.add(registerComponent("btn 4", new JButton("jbutton")));
 306 
 307         return jframe;
 308     }
 309 
 310     protected void customizeHierarchy() {
 311         ((Container)getComponent("jframe")).setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
 312         ((Container)getComponent("jpanel")).setFocusCycleRoot(true);
 313     }
 314 
 315     protected Map<String, String> getForwardOrder() {
 316         Map<String, String> order = new HashMap<String, String>();
 317         order.put("jframe", "btn 1");
 318         order.put("btn 1", "btn 2");
 319         order.put("btn 2", "btn 3");
 320         order.put("btn 3", "btn 2");
 321         order.put("btn 4", "btn 1");
 322         order.put("jpanel", "btn 2");
 323         return order;
 324     }
 325 
 326     protected Map<String, String> getBackwardOrder() {
 327         Map<String, String> order = new HashMap<String, String>();
 328         order.put("btn 4", "btn 2");
 329         order.put("btn 3", "btn 2");
 330         order.put("btn 2", "btn 3");
 331         order.put("btn 1", "btn 4");
 332         return order;
 333     }
 334 
 335     protected String[] getContainersToTest() {
 336         return new String[] {"jframe", "jpanel"};
 337     }
 338 
 339     protected String getDefaultComp(String focusCycleRoot_id) {
 340         if ("jframe".equals(focusCycleRoot_id)) {
 341             return "btn 1";
 342         } else if ("jpanel".equals(focusCycleRoot_id)) {
 343             return "btn 2";
 344         }
 345         return null;
 346     }
 347 
 348     protected String getFirstComp(String focusCycleRoot_id) {
 349         return getDefaultComp(focusCycleRoot_id);
 350     }
 351 
 352     protected String getLastComp(String focusCycleRoot_id) {
 353         if ("jframe".equals(focusCycleRoot_id)) {
 354             return "btn 4";
 355         } else if ("jpanel".equals(focusCycleRoot_id)) {
 356             return "btn 3";
 357         }
 358         return null;
 359     }
 360 }
 361 
 362 /*
 363  * frame [ container(provider) [...] comp1(unfocusable) comp2 ]
 364  * - getComponentBefore(<frame>, <comp2>) should return <container>'s last.
 365  */
 366 class PolicyTest4 extends AbstractPolicyTest {
 367 
 368     protected Frame createFrame() {
 369         JFrame jframe = (JFrame) registerComponent("jframe", new JFrame("Test Frame"));
 370         jframe.setLayout(new FlowLayout());
 371 
 372         Container cont = (Container)registerComponent("jpanel", new JPanel());
 373         cont.add(registerComponent("btn 1", new JButton("jbutton")));
 374         cont.add(registerComponent("btn 2", new JButton("jbutton")));
 375         jframe.add(cont);
 376 
 377         jframe.add(registerComponent("btn 3", new JButton("jbutton")));
 378         jframe.add(registerComponent("btn 4", new JButton("jbutton")));
 379 
 380         return jframe;
 381     }
 382 
 383     protected void customizeHierarchy() {
 384         ((Container)getComponent("jframe")).setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
 385         ((Container)getComponent("jpanel")).setFocusTraversalPolicyProvider(true);
 386         ((JButton)getComponent("btn 3")).setFocusable(false);
 387     }
 388 
 389     protected Map<String, String> getBackwardOrder() {
 390         Map<String, String> order = new HashMap<String, String>();
 391         order.put("btn 4", "btn 2");
 392         order.put("btn 2", "btn 1");
 393         order.put("btn 1", "btn 4");
 394         return order;
 395     }
 396 
 397     // no testing
 398     protected Map<String, String> getForwardOrder() {
 399         return null;
 400     }
 401     protected String[] getContainersToTest() {
 402         return null;
 403     }
 404     protected String getDefaultComp(String focusCycleRoot_id) {
 405         return null;
 406     }
 407     protected String getFirstComp(String focusCycleRoot_id) {
 408         return null;
 409     }
 410     protected String getLastComp(String focusCycleRoot_id) {
 411         return null;
 412     }
 413 }
 414 
 415 /*
 416  * frame [ container(root) [...] comp1(unfocusable) comp2 ]
 417  * - getComponentBefore(<frame>, <comp2>) should return <container>'s default.
 418  */
 419 class PolicyTest5 extends AbstractPolicyTest {
 420 
 421     protected Frame createFrame() {
 422         JFrame jframe = (JFrame) registerComponent("jframe", new JFrame("Test Frame"));
 423         jframe.setLayout(new FlowLayout());
 424 
 425         Container cont = (Container)registerComponent("jpanel", new JPanel());
 426         cont.add(registerComponent("btn 1", new JButton("jbutton")));
 427         cont.add(registerComponent("btn 2", new JButton("jbutton")));
 428         jframe.add(cont);
 429 
 430         jframe.add(registerComponent("btn 3", new JButton("jbutton")));
 431         jframe.add(registerComponent("btn 4", new JButton("jbutton")));
 432 
 433         return jframe;
 434     }
 435 
 436     protected void customizeHierarchy() {
 437         ((Container)getComponent("jframe")).setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
 438         ((Container)getComponent("jpanel")).setFocusCycleRoot(true);
 439         ((JButton)getComponent("btn 3")).setFocusable(false);
 440     }
 441 
 442     protected Map<String, String> getBackwardOrder() {
 443         Map<String, String> order = new HashMap<String, String>();
 444         order.put("btn 4", "btn 1");
 445         order.put("btn 2", "btn 1");
 446         order.put("btn 1", "btn 2");
 447         return order;
 448     }
 449 
 450     // no testing
 451     protected Map<String, String> getForwardOrder() {
 452         return null;
 453     }
 454     protected String[] getContainersToTest() {
 455         return null;
 456     }
 457     protected String getDefaultComp(String focusCycleRoot_id) {
 458         return null;
 459     }
 460     protected String getFirstComp(String focusCycleRoot_id) {
 461         return null;
 462     }
 463     protected String getLastComp(String focusCycleRoot_id) {
 464         return null;
 465     }
 466 }
 467 
 468 /*
 469  * frame [ comp container(provider)(focusable) [...] comp ]
 470  * - transfering focus through a focusable provider.
 471  */
 472 class PolicyTest6 extends AbstractPolicyTest {
 473 
 474     protected Frame createFrame() {
 475         JFrame jframe = (JFrame) registerComponent("jframe", new JFrame("Test Frame"));
 476         jframe.setLayout(new FlowLayout());
 477 
 478         jframe.add(registerComponent("btn 1", new JButton("jbutton")));
 479 
 480         Container cont = (Container)registerComponent("jpanel", new JPanel());
 481         cont.add(registerComponent("btn 2", new JButton("jbutton")));
 482         cont.add(registerComponent("btn 3", new JButton("jbutton")));
 483         jframe.add(cont);
 484 
 485         jframe.add(registerComponent("btn 4", new JButton("jbutton")));
 486 
 487         return jframe;
 488     }
 489 
 490     protected void customizeHierarchy() {
 491         ((Container)getComponent("jframe")).setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
 492         ((Container)getComponent("jpanel")).setFocusTraversalPolicy(new LayoutFocusTraversalPolicy() {
 493                 public Component getDefaultComponent(Container aContainer) {
 494                     return getComponent("btn 2");
 495                 }
 496             });
 497         ((Container)getComponent("jpanel")).setFocusTraversalPolicyProvider(true);
 498         ((Container)getComponent("jpanel")).setFocusable(true);
 499     }
 500 
 501     protected Map<String, String> getForwardOrder() {
 502         Map<String, String> order = new HashMap<String, String>();
 503         order.put("jframe", "btn 1");
 504         order.put("btn 1", "jpanel");
 505         order.put("btn 2", "btn 3");
 506         order.put("btn 3", "btn 4");
 507         order.put("btn 4", "btn 1");
 508         order.put("jpanel", "btn 2");
 509         return order;
 510     }
 511 
 512     protected Map<String, String> getBackwardOrder() {
 513         Map<String, String> order = new HashMap<String, String>();
 514         order.put("btn 4", "btn 3");
 515         order.put("btn 3", "btn 2");
 516         order.put("btn 2", "jpanel");
 517         order.put("btn 1", "btn 4");
 518         order.put("jpanel", "btn 1");
 519         return order;
 520     }
 521 
 522     protected String[] getContainersToTest() {
 523         return new String[] {"jpanel"};
 524     }
 525 
 526     protected String getDefaultComp(String focusCycleRoot_id) {
 527         return "btn 2";
 528     }
 529 
 530     protected String getFirstComp(String focusCycleRoot_id) {
 531         return "jpanel";
 532     }
 533 
 534     protected String getLastComp(String focusCycleRoot_id) {
 535         return "btn 3";
 536     }
 537 }
 538 
 539 /*
 540  * frame [ comp container(root)(focusable) [...] comp ]
 541  * - transfering focus through a focusable root.
 542  */
 543 class PolicyTest7 extends AbstractPolicyTest {
 544 
 545     protected Frame createFrame() {
 546         JFrame jframe = (JFrame) registerComponent("jframe", new JFrame("Test Frame"));
 547         jframe.setLayout(new FlowLayout());
 548 
 549         jframe.add(registerComponent("btn 1", new JButton("jbutton")));
 550 
 551         Container cont = (Container)registerComponent("jpanel", new JPanel());
 552         cont.add(registerComponent("btn 2", new JButton("jbutton")));
 553         cont.add(registerComponent("btn 3", new JButton("jbutton")));
 554         jframe.add(cont);
 555 
 556         jframe.add(registerComponent("btn 4", new JButton("jbutton")));
 557 
 558         return jframe;
 559     }
 560 
 561     protected void customizeHierarchy() {
 562         ((Container)getComponent("jframe")).setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
 563         ((Container)getComponent("jpanel")).setFocusTraversalPolicy(new LayoutFocusTraversalPolicy() {
 564                 public Component getDefaultComponent(Container aContainer) {
 565                     return getComponent("btn 2");
 566                 }
 567             });
 568         ((Container)getComponent("jpanel")).setFocusCycleRoot(true);
 569         ((Container)getComponent("jpanel")).setFocusable(true);
 570     }
 571 
 572     protected Map<String, String> getForwardOrder() {
 573         Map<String, String> order = new HashMap<String, String>();
 574         order.put("jframe", "btn 1");
 575         order.put("btn 1", "jpanel");
 576         order.put("btn 2", "btn 3");
 577         order.put("btn 3", "jpanel");
 578         order.put("btn 4", "btn 1");
 579         order.put("jpanel", "btn 2");
 580         return order;
 581     }
 582 
 583     protected Map<String, String> getBackwardOrder() {
 584         Map<String, String> order = new HashMap<String, String>();
 585         order.put("btn 4", "btn 2");
 586         order.put("btn 3", "btn 2");
 587         order.put("btn 2", "jpanel");
 588         order.put("btn 1", "btn 4");
 589         order.put("jpanel", "btn 1");
 590         return order;
 591     }
 592 
 593     protected String[] getContainersToTest() {
 594         return new String[] {"jpanel"};
 595     }
 596 
 597     protected String getDefaultComp(String focusCycleRoot_id) {
 598         return "btn 2";
 599     }
 600 
 601     protected String getFirstComp(String focusCycleRoot_id) {
 602         return "jpanel";
 603     }
 604 
 605     protected String getLastComp(String focusCycleRoot_id) {
 606         return "btn 3";
 607     }
 608 }
 609 
 610 /*
 611  * frame [ comp1 comp2 container1(provider) [...] container2(root) [...] ]
 612  * - verifies a case when a provider is followed by a root.
 613  */
 614 class PolicyTest8 extends AbstractPolicyTest {
 615 
 616     protected Frame createFrame() {
 617         JFrame jframe = (JFrame) registerComponent("frame", new JFrame("Test Frame"));
 618         jframe.setLayout(new FlowLayout());
 619 
 620         jframe.add(registerComponent("btn-1", new JButton("jbutton")));
 621         jframe.add(registerComponent("btn-2", new JButton("jbutton")));
 622 
 623         Container cont1 = (Container)registerComponent("panel-1", new JPanel());
 624         cont1.add(registerComponent("btn-3", new JButton("jbutton")));
 625         cont1.add(registerComponent("btn-4", new JButton("jbutton")));
 626         cont1.add(registerComponent("btn-5", new JButton("jbutton")));
 627 
 628         Container cont2 = (Container)registerComponent("panel-2", new JPanel());
 629         cont2.add(registerComponent("btn-6", new JButton("jbutton")));
 630         cont2.add(registerComponent("btn-7", new JButton("jbutton")));
 631         cont2.add(registerComponent("btn-8", new JButton("jbutton")));
 632 
 633         jframe.add(cont1);
 634         jframe.add(cont2);
 635 
 636         return jframe;
 637     }
 638 
 639     protected void customizeHierarchy() {
 640         ((Container)getComponent("panel-1")).setFocusTraversalPolicyProvider(true);
 641         ((Container)getComponent("panel-1")).setFocusTraversalPolicy(new LayoutFocusTraversalPolicy() {
 642                 public Component getDefaultComponent(Container aContainer) {
 643                     return getComponent("btn-4");
 644                 }
 645             });
 646 
 647         ((Container)getComponent("panel-2")).setFocusCycleRoot(true);
 648         ((Container)getComponent("panel-2")).setFocusTraversalPolicy(new LayoutFocusTraversalPolicy() {
 649                 public Component getDefaultComponent(Container aContainer) {
 650                     return getComponent("btn-7");
 651                 }
 652             });
 653     }
 654 
 655     protected Map<String, String> getForwardOrder() {
 656         Map<String, String> order = new HashMap<String, String>();
 657         order.put("frame", "btn-1");
 658         order.put("btn-1", "btn-2");
 659         order.put("btn-2", "btn-4");
 660         order.put("btn-3", "btn-4");
 661         order.put("btn-4", "btn-5");
 662         order.put("btn-5", "btn-7");
 663         order.put("btn-6", "btn-7");
 664         order.put("btn-7", "btn-8");
 665         order.put("btn-8", "btn-6");
 666         order.put("panel-1", "btn-4");
 667         order.put("panel-2", "btn-7");
 668         return order;
 669     }
 670 
 671     protected Map<String, String> getBackwardOrder() {
 672         Map<String, String> order = new HashMap<String, String>();
 673         order.put("btn-1", "btn-5");
 674         order.put("btn-2", "btn-1");
 675         order.put("btn-3", "btn-2");
 676         order.put("btn-4", "btn-3");
 677         order.put("btn-5", "btn-4");
 678         order.put("btn-6", "btn-8");
 679         order.put("btn-7", "btn-6");
 680         order.put("btn-8", "btn-7");
 681         return order;
 682     }
 683 
 684     protected String[] getContainersToTest() {
 685         return new String[] {"frame", "panel-1", "panel-2"};
 686     }
 687 
 688     protected String getDefaultComp(String focusCycleRoot_id) {
 689         if ("frame".equals(focusCycleRoot_id)) {
 690             return "btn-1";
 691         } else if ("panel-1".equals(focusCycleRoot_id)) {
 692             return "btn-4";
 693         } else if ("panel-2".equals(focusCycleRoot_id)) {
 694             return "btn-7";
 695         }
 696         return null;
 697     }
 698 
 699     protected String getFirstComp(String focusCycleRoot_id) {
 700         if ("frame".equals(focusCycleRoot_id)) {
 701             return "btn-1";
 702         } else if ("panel-1".equals(focusCycleRoot_id)) {
 703             return "btn-3";
 704         } else if ("panel-2".equals(focusCycleRoot_id)) {
 705             return "btn-6";
 706         }
 707         return null;
 708     }
 709 
 710     protected String getLastComp(String focusCycleRoot_id) {
 711         if ("frame".equals(focusCycleRoot_id)) {
 712             return "btn-5";
 713         } else if ("panel-1".equals(focusCycleRoot_id)) {
 714             return "btn-5";
 715         } else if ("panel-2".equals(focusCycleRoot_id)) {
 716             return "btn-8";
 717         }
 718         return null;
 719     }
 720 }
 721 
 722 /*
 723  * frame [ comp1 comp2 container1(root) [...] container2(provider) [...] ]
 724  * - verifies a case when a root is followed by a provider.
 725  */
 726 class PolicyTest9 extends AbstractPolicyTest {
 727 
 728     protected Frame createFrame() {
 729         JFrame jframe = (JFrame) registerComponent("frame", new JFrame("Test Frame"));
 730         jframe.setLayout(new FlowLayout());
 731 
 732         jframe.add(registerComponent("btn-1", new JButton("jbutton")));
 733         jframe.add(registerComponent("btn-2", new JButton("jbutton")));
 734 
 735         Container cont1 = (Container)registerComponent("panel-1", new JPanel());
 736         cont1.add(registerComponent("btn-3", new JButton("jbutton")));
 737         cont1.add(registerComponent("btn-4", new JButton("jbutton")));
 738         cont1.add(registerComponent("btn-5", new JButton("jbutton")));
 739 
 740         Container cont2 = (Container)registerComponent("panel-2", new JPanel());
 741         cont2.add(registerComponent("btn-6", new JButton("jbutton")));
 742         cont2.add(registerComponent("btn-7", new JButton("jbutton")));
 743         cont2.add(registerComponent("btn-8", new JButton("jbutton")));
 744 
 745         jframe.add(cont1);
 746         jframe.add(cont2);
 747 
 748         return jframe;
 749     }
 750 
 751     protected void customizeHierarchy() {
 752         ((Container)getComponent("panel-1")).setFocusCycleRoot(true);
 753         ((Container)getComponent("panel-1")).setFocusTraversalPolicy(new LayoutFocusTraversalPolicy() {
 754                 public Component getDefaultComponent(Container aContainer) {
 755                     return getComponent("btn-4");
 756                 }
 757             });
 758 
 759         ((Container)getComponent("panel-2")).setFocusTraversalPolicyProvider(true);
 760         ((Container)getComponent("panel-2")).setFocusTraversalPolicy(new LayoutFocusTraversalPolicy() {
 761                 public Component getDefaultComponent(Container aContainer) {
 762                     return getComponent("btn-7");
 763                 }
 764             });
 765     }
 766 
 767     protected Map<String, String> getForwardOrder() {
 768         Map<String, String> order = new HashMap<String, String>();
 769         order.put("frame", "btn-1");
 770         order.put("btn-1", "btn-2");
 771         order.put("btn-2", "btn-4");
 772         order.put("btn-3", "btn-4");
 773         order.put("btn-4", "btn-5");
 774         order.put("btn-5", "btn-3");
 775         order.put("btn-6", "btn-7");
 776         order.put("btn-7", "btn-8");
 777         order.put("btn-8", "btn-1");
 778         order.put("panel-1", "btn-4");
 779         order.put("panel-2", "btn-7");
 780         return order;
 781     }
 782 
 783     protected Map<String, String> getBackwardOrder() {
 784         Map<String, String> order = new HashMap<String, String>();
 785         order.put("btn-1", "btn-8");
 786         order.put("btn-2", "btn-1");
 787         order.put("btn-3", "btn-5");
 788         order.put("btn-4", "btn-3");
 789         order.put("btn-5", "btn-4");
 790         order.put("btn-6", "btn-4");
 791         order.put("btn-7", "btn-6");
 792         order.put("btn-8", "btn-7");
 793         return order;
 794     }
 795 
 796     protected String[] getContainersToTest() {
 797         return new String[] {"frame", "panel-1", "panel-2"};
 798     }
 799 
 800     protected String getDefaultComp(String focusCycleRoot_id) {
 801         if ("frame".equals(focusCycleRoot_id)) {
 802             return "btn-1";
 803         } else if ("panel-1".equals(focusCycleRoot_id)) {
 804             return "btn-4";
 805         } else if ("panel-2".equals(focusCycleRoot_id)) {
 806             return "btn-7";
 807         }
 808         return null;
 809     }
 810 
 811     protected String getFirstComp(String focusCycleRoot_id) {
 812         if ("frame".equals(focusCycleRoot_id)) {
 813             return "btn-1";
 814         } else if ("panel-1".equals(focusCycleRoot_id)) {
 815             return "btn-3";
 816         } else if ("panel-2".equals(focusCycleRoot_id)) {
 817             return "btn-6";
 818         }
 819         return null;
 820     }
 821 
 822     protected String getLastComp(String focusCycleRoot_id) {
 823         if ("frame".equals(focusCycleRoot_id)) {
 824             return "btn-8";
 825         } else if ("panel-1".equals(focusCycleRoot_id)) {
 826             return "btn-5";
 827         } else if ("panel-2".equals(focusCycleRoot_id)) {
 828             return "btn-8";
 829         }
 830         return null;
 831     }
 832 }
 833 
 834 /*
 835  * frame [ container0 [...] container1(root) [ comp1 comp2 container2(provider) [...] ] ]
 836  * - verifies a case when a provider is nested in a root.
 837  */
 838 class PolicyTest10 extends AbstractPolicyTest {
 839 
 840     protected Frame createFrame() {
 841         JFrame jframe = (JFrame) registerComponent("frame", new JFrame("Test Frame"));
 842         jframe.setLayout(new GridLayout(2, 1));
 843 
 844         Container cont0 = new JPanel();
 845         cont0.add(registerComponent("btn-1", new JButton("jbutton")));
 846         cont0.add(registerComponent("btn-2", new JButton("jbutton")));
 847 
 848         Container cont1 = (Container)registerComponent("panel-1", new JPanel());
 849         cont1.add(registerComponent("btn-3", new JButton("jbutton")));
 850         cont1.add(registerComponent("btn-4", new JButton("jbutton")));
 851 
 852         Container cont2 = (Container)registerComponent("panel-2", new JPanel());
 853         cont2.add(registerComponent("btn-5", new JButton("jbutton")));
 854         cont2.add(registerComponent("btn-6", new JButton("jbutton")));
 855 
 856         cont1.add(cont2);
 857         jframe.add(cont0);
 858         jframe.add(cont1);
 859 
 860         return jframe;
 861     }
 862 
 863     protected void customizeHierarchy() {
 864         ((Container)getComponent("panel-1")).setFocusCycleRoot(true);
 865         ((Container)getComponent("panel-1")).setFocusTraversalPolicy(new LayoutFocusTraversalPolicy() {
 866                 public Component getDefaultComponent(Container aContainer) {
 867                     return getComponent("panel-2");
 868                 }
 869             });
 870         ((Container)getComponent("panel-2")).setFocusTraversalPolicyProvider(true);
 871         ((Container)getComponent("panel-2")).setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
 872     }
 873 
 874     protected Map<String, String> getForwardOrder() {
 875         Map<String, String> order = new HashMap<String, String>();
 876         order.put("frame", "btn-1");
 877         order.put("btn-1", "btn-2");
 878         order.put("btn-2", "panel-2");
 879         order.put("btn-3", "btn-4");
 880         order.put("btn-4", "btn-5");
 881         order.put("btn-5", "btn-6");
 882         order.put("btn-6", "btn-3");
 883         order.put("panel-1", "panel-2");
 884         order.put("panel-2", "btn-5");
 885         return order;
 886     }
 887 
 888     protected Map<String, String> getBackwardOrder() {
 889         Map<String, String> order = new HashMap<String, String>();
 890         order.put("btn-1", "btn-2");
 891         order.put("btn-2", "btn-1");
 892         order.put("btn-3", "btn-6");
 893         order.put("btn-4", "btn-3");
 894         order.put("btn-5", "btn-4");
 895         order.put("btn-6", "btn-5");
 896         return order;
 897     }
 898 
 899     protected String[] getContainersToTest() {
 900         return new String[] {"frame", "panel-1", "panel-2"};
 901     }
 902 
 903     protected String getDefaultComp(String focusCycleRoot_id) {
 904         if ("frame".equals(focusCycleRoot_id)) {
 905             return "btn-1";
 906         } else if ("panel-1".equals(focusCycleRoot_id)) {
 907             return "panel-2";
 908         } else if ("panel-2".equals(focusCycleRoot_id)) {
 909             return "btn-5";
 910         }
 911         return null;
 912     }
 913 
 914     protected String getFirstComp(String focusCycleRoot_id) {
 915         if ("frame".equals(focusCycleRoot_id)) {
 916             return "btn-1";
 917         } else if ("panel-1".equals(focusCycleRoot_id)) {
 918             return "btn-3";
 919         } else if ("panel-2".equals(focusCycleRoot_id)) {
 920             return "btn-5";
 921         }
 922         return null;
 923     }
 924 
 925     protected String getLastComp(String focusCycleRoot_id) {
 926         if ("frame".equals(focusCycleRoot_id)) {
 927             return "btn-2";
 928         } else {
 929             return "btn-6";
 930         }
 931     }
 932 }
 933 
 934 /*
 935  * frame [ container(root) [...] comp ]
 936  * - getDefaultComponent(<frame>) should implicitly down-cycle into the <container>.
 937  * - getFirstComponent(<frame>) should implicitly down-cycle into the <container>.
 938  */
 939 class PolicyTest11 extends AbstractPolicyTest {
 940     protected Frame createFrame() {
 941         JFrame jframe = (JFrame) registerComponent("jframe", new JFrame("Test Frame"));
 942         jframe.setLayout(new FlowLayout());
 943 
 944         Container cont = (Container)registerComponent("jpanel", new JPanel());
 945         cont.add(registerComponent("btn-1", new JButton("jbutton")));
 946         cont.add(registerComponent("btn-2", new JButton("jbutton")));
 947 
 948         jframe.add(cont);
 949         jframe.add(registerComponent("btn-3", new JButton("jbutton")));
 950 
 951         return jframe;
 952     }
 953 
 954     protected void customizeHierarchy() {
 955         ((Container)getComponent("jframe")).setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
 956         ((Container)getComponent("jpanel")).setFocusCycleRoot(true);
 957     }
 958 
 959     protected Map<String, String> getForwardOrder() {
 960         Map<String, String> order = new HashMap<String, String>();
 961         order.put("jframe", "btn-1");
 962         order.put("btn-1", "btn-2");
 963         order.put("btn-2", "btn-1");
 964         order.put("btn-3", "btn-1");
 965         return order;
 966     }
 967 
 968     protected Map<String, String> getBackwardOrder() {
 969         Map<String, String> order = new HashMap<String, String>();
 970         order.put("btn-3", "btn-1");
 971         order.put("btn-2", "btn-1");
 972         order.put("btn-1", "btn-2");
 973         order.put("jframe", "btn-3");
 974         return order;
 975     }
 976 
 977     protected String[] getContainersToTest() {
 978         return new String[] {"jframe"};
 979     }
 980 
 981     protected String getDefaultComp(String focusCycleRoot_id) {
 982         return "btn-1";
 983     }
 984 
 985     protected String getFirstComp(String focusCycleRoot_id) {
 986         return "btn-1";
 987     }
 988 
 989     protected String getLastComp(String focusCycleRoot_id) {
 990         return "btn-3";
 991     }
 992 }