Writing a custom FocusTraversalPolicy

[JDK 1.4+] Extend from FocusTraversalPolicy and implement the abstract methods!

Main.java:

import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
  
public class Main extends JFrame
{
   JLabel label = new JLabel("Forward: TAB or alt-f, Backward: SHIFT-TAB or alt-b");
   ArrayList textfields = new ArrayList();
   JRadioButton leftToRight = new JRadioButton("Left to right", true);
   JRadioButton topToBottom = new JRadioButton("Top to bottom");
  
   public Main() {
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
      Container contentPane = getContentPane();
      contentPane.setLayout(new BorderLayout(10, 10));
  
      JPanel topPanel = new JPanel(new GridLayout(3, 1));
      topPanel.add(new JLabel("Change the focus traversal policy"));
 
      ButtonGroup group = new ButtonGroup();
      group.add(leftToRight);
      group.add(topToBottom);
      topPanel.add(leftToRight); 
      topPanel.add(topToBottom);
 
      JPanel bottomPanel = new JPanel(new GridLayout(4, 2));
      for (int i=0; i<4; i++) {
         for (int j=0; j<2; j++) { 
            JTextField textfield = new JTextField("" + i + ", " + j);
            textfields.add(textfield);
            bottomPanel.add(textfield);
         }
      }     
  
      contentPane.add(BorderLayout.NORTH, topPanel);
      contentPane.add(BorderLayout.SOUTH, bottomPanel);
  
      bottomPanel.setFocusTraversalPolicy(new MyFocusTraversalPolicy());
      bottomPanel.setFocusCycleRoot(true);
   } 
  
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(350, 200);
      main.setVisible(true);
   }
 
   class MyFocusTraversalPolicy extends FocusTraversalPolicy
   {
      // Returns the Component that should receive the focus after aComponent.
      public Component getComponentAfter(Container focusCycleRoot, Component aComponent) {
         if (leftToRight.isSelected()) {
            int index = textfields.indexOf(aComponent);
            return (Component) textfields.get((index + 1) % textfields.size());
         }
         else if (topToBottom.isSelected()) {
            int index = textfields.indexOf(aComponent);
            int nextIndex = (index + 2) % textfields.size();
            if (nextIndex == 0) nextIndex = 1;
            else if (nextIndex == 1) nextIndex = 0;
            return (Component) textfields.get(nextIndex);
         }
 
         if (!aComponent.isEnabled()) {
            return getComponentAfter(focusCycleRoot, aComponent);
         }          
 
         return aComponent;
      }
  
      // Returns the Component that should receive the focus before aComponent.
      public Component getComponentBefore(Container focusCycleRoot, Component aComponent) {
         if (leftToRight.isSelected()) {
            int index = textfields.indexOf(aComponent);
            index--;
            if (index < 0) index = textfields.size() - 1;
            return (Component) textfields.get(index);
         }
         else if (topToBottom.isSelected()) {
            int index = textfields.indexOf(aComponent);
            index -= 2;
            if (index < 0) index = textfields.size() - 3 - index;
            //else if (index == 0) index = textfields.size() - 1;
            //else if (index == 1) index = textfields.size() - 2;
            return (Component) textfields.get(index);
         }
 
         return aComponent;
      }
  
      // Returns the default Component to focus.
      public Component getDefaultComponent(Container focusCycleRoot) {
         return (Component) textfields.get(0);
      }
 
      // Returns the first Component in the traversal cycle.
      public Component getFirstComponent(Container focusCycleRoot) {
         return (Component) textfields.get(0);
      }
 
      // Returns the Component that should receive the focus when a Window is made visible for the first time. 
      public Component getInitialComponent(Window window) {
         return leftToRight;
      }
 
      // Returns the last Component in the traversal cycle. 
      public Component getLastComponent(Container focusCycleRoot) {
         return (Component) textfields.get(textfields.size() - 1);
      }
   }
}