Force the JScrollPane to scroll to the next JTextField when I press the TAB-Key

There are three steps to this:

1. Listen for focus events coming from the components that you want to scroll to. (This works for most component classes, not just JTextField.)

2. In the event listener, find the location of the component that now has focus with getBounds().

3. Ask the scrolled component to make that location visible with scrollRectToVisible(). NOTE! The obvious thing to call scrollRectToVisible on is the JScrollPane, which will compile fine but won’t do what you want. You must call scrollRectToVisible on the object contained in viewport of the scrollpane.

This Forte-generated example shows how this works for a simple panel containing a number of JTextFields. Notice that scrollRectToVisible is called on the JPanel containing the text fields.

TestFocus.java:

public class TestFocus extends javax.swing.JFrame {
 
    /** Creates new form TestFocus */
    public TestFocus() {
        initComponents();
    }
 
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {
        scrollPane = new javax.swing.JScrollPane();
        panel = new javax.swing.JPanel();
        jTextField1 = new javax.swing.JTextField();
        jTextField2 = new javax.swing.JTextField();
        jTextField3 = new javax.swing.JTextField();
        jTextField4 = new javax.swing.JTextField();
         
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                exitForm(evt);
            }
        });
        
        scrollPane.setPreferredSize(new java.awt.Dimension(120, 80));
        panel.setLayout(new java.awt.GridLayout(0, 1, 0, 15));
        
        jTextField1.setFont(new java.awt.Font("Dialog", 0, 18));
        jTextField1.setText("jTextField1");
        jTextField1.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                jTextFieldFocusGained(evt);
            }
        });
         
        panel.add(jTextField1);
        
        jTextField2.setFont(new java.awt.Font("Dialog", 0, 18));
        jTextField2.setText("jTextField2");
        jTextField2.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                jTextFieldFocusGained(evt);
            }
        });
        
        panel.add(jTextField2);
        
        jTextField3.setFont(new java.awt.Font("Dialog", 0, 18));
        jTextField3.setText("jTextField3");
        jTextField3.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                jTextFieldFocusGained(evt);
            }
        });
        
        panel.add(jTextField3);
        
        jTextField4.setFont(new java.awt.Font("Dialog", 0, 18));
        jTextField4.setText("jTextField4");
        jTextField4.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                jTextFieldFocusGained(evt);
            }
        });
        
        panel.add(jTextField4);
        
        scrollPane.setViewportView(panel);
        
        getContentPane().add(scrollPane, java.awt.BorderLayout.CENTER);
        
        pack();
    }
 
    private void jTextFieldFocusGained(java.awt.event.FocusEvent evt) {
        java.awt.Component focusedComponent = evt.getComponent();
        panel.scrollRectToVisible(focusedComponent.getBounds(null));
        repaint();
    }
 
    /** Exit the Application */
    private void exitForm(java.awt.event.WindowEvent evt) {
        System.exit(0);
    }
 
    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        new TestFocus().show();
    }
 
    // Variables declaration - do not modify
    private javax.swing.JScrollPane scrollPane;
    private javax.swing.JPanel panel;
    private javax.swing.JTextField jTextField1;
    private javax.swing.JTextField jTextField2;
    private javax.swing.JTextField jTextField3;
    private javax.swing.JTextField jTextField4;
    // End of variables declaration

}

If your panel of components contains a JTextArea, or another JTextComponent subclass, then be aware that those components will absorb TABs into themselves instead of allowing the TAB to change focus. You can disable this behavior by creating a subclass that overrides isManagingFocus() to always return false.