Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

How can we prevent JTabbedPanes from transferring focus to components outside of the tabs during tab

JamesLee83Oct 10 2013 — edited Nov 13 2013

Hi,

I noticed a strange focus traversal behavior of JTabbedPane.

During tab traversal (when the user's intention is just to switch between tabs), the focus is transferred to a component outside of the tabs (if there is a component after/below the JTabbedPane component), if using Java 6. For example, if using the SSCCE below...

import java.awt.BorderLayout;

import java.awt.event.FocusAdapter;

import java.awt.event.FocusEvent;

import java.awt.event.KeyEvent;


import javax.swing.Box;

import javax.swing.BoxLayout;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTabbedPane;

import javax.swing.JTextField;

import javax.swing.SwingUtilities;


public class TabbedPaneTest extends JPanel {


    public TabbedPaneTest() {

        super(new BorderLayout());


        JTabbedPane tabbedPane = new JTabbedPane();


        tabbedPane.addTab("Tab 1", buildPanelWithChildComponents());

        tabbedPane.setMnemonicAt(0, KeyEvent.VK_1);


        tabbedPane.addTab("Tab 2", buildPanelWithChildComponents());

        tabbedPane.setMnemonicAt(1, KeyEvent.VK_2);


        tabbedPane.addTab("Tab 3", buildPanelWithChildComponents());

        tabbedPane.setMnemonicAt(2, KeyEvent.VK_3);


        tabbedPane.addTab("Tab 4", buildPanelWithChildComponents());

        tabbedPane.setMnemonicAt(3, KeyEvent.VK_4);


        JPanel panel = new JPanel(new BorderLayout());

        panel.add(tabbedPane);


        JButton button = new JButton("Dummy component that gains focus when switching tabs");

        panel.add(button, BorderLayout.SOUTH);


        /*

         * To replicate the focus traversal issue, please follow these steps -

         * 1) Run this program in Java 6; and then

         * 2) Click on a child component inside any tab; and then

         * 3) Click on any other tab (or use the mnemonic keys ALT + 1 to ALT 4).

         */

        button.addFocusListener(new FocusAdapter() {

            @Override

            public void focusGained(FocusEvent e) {

                System.err.println("Gained focus (not supposed to when just switching tabs).");

            }

        });


        add(new JScrollPane(panel));

    }


    private JPanel buildPanelWithChildComponents() {

        JPanel panel = new JPanel();

        BoxLayout boxlayout = new BoxLayout(panel, BoxLayout.PAGE_AXIS);

        panel.setLayout(boxlayout);


        panel.add(Box.createVerticalStrut(3));


        for (int i = 0; i < 4; i++) {

            panel.add(new JTextField(10));

            panel.add(Box.createVerticalStrut(3));

        }


        return panel;

    }


    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {

            public void run() {

                JFrame frame = new JFrame("Test for Java 6");

                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


                frame.add(new TabbedPaneTest());


                frame.pack();

                frame.setVisible(true);

            }

        });

    }


}

... Then we can replicate this behavior by following these steps:

1) Run the program in Java 6; and then

2) Click on a child component in any of the tabs; and then

3) Click on any other tab (or use the mnemonic keys 'ALT + 1' to 'ALT + 4').

At step 3 (upon selecting any other tab), the focus would go to the component below the JTabbedPane first (hence the printed message in the console), before actually going to the selected tab.

This does not occur in Java 7, so I'm assuming it is a bug that is fixed. And I know that Oracle suggests that we should use Java 7 nowadays.

The problem is: We need to stick to Java 6 for a certain application. So I'm looking for a way to fix this issue for all our JTabbedPane components while using Java 6.

So, is there a way to prevent JTabbedPanes from passing the focus to components outside of the tabs during tab traversal (e.g. when users are just switching between tabs), in Java 6?

Note: I've read the release notes between Java 6u45 to Java 7u15, but I was unable to find any changes related to the JTabbedPane component. So any pointers on this would be deeply appreciated.

Regards,

James

Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Dec 11 2013
Added on Oct 10 2013
6 comments
4,212 views