Nov 162012
 

Today I set out to accomplish something that appeared to be quite simple. However, it took me quite a few hours and lots of reading to find a solution. I do hope that this will be useful to other developers!

I have been working a JPanel form with a lot of different components on it, including JTextFields, JDateChoosers and some custom Swing components. And today I wanted to exclude some of the controls from the tab order. The controls I wanted to exclude were enabled but set as not editable, to allow the user to copy the values as required.

The first thing I tried was setting the components as not focusable. However, that meant that I couldn’t select the text with the mouse pointer anymore. So back to the drawing board.

I moved on to reading about the FocusTraversalPolicy mechanism (which I have never used before). And after much trial and error, I found this very simple solution. Just extend the class LayoutFocusTraversalPolicy, overriding the accept method as required. Here is the newly created class:

public class ExclusionFocusTraversalPolicy 
        extends LayoutFocusTraversalPolicy {

    private ArrayList components = new ArrayList();

    public void addExcludedComponent(Component component) {
        components.add(component);
    }

    @Override
    protected boolean accept(Component aComponent) {
        if (components.contains(aComponent)) {
            return false;
        }
        return super.accept(aComponent);
    }
}

And then in the form after adding the components call:

ExclusionFocusTraversalPolicy policy = new ExclusionFocusTraversalPolicy();
// add all the desired components to the exclusion list
policy.addExcludedComponent(textField);
setFocusTraversalPolicy(policy);
setFocusTraversalPolicyProvider(true);

That is it. Now when tabbing through the form, all the components in the exclusion list are skipped!