org.jdal.swing.form.FormFocusTransversalPolicy.java Source code

Java tutorial

Introduction

Here is the source code for org.jdal.swing.form.FormFocusTransversalPolicy.java

Source

/*
 * Copyright 2008-2011 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jdal.swing.form;

import java.awt.Component;
import java.awt.Container;
import java.awt.FocusTraversalPolicy;
import java.util.ArrayList;

import javax.swing.JComboBox;
import javax.swing.JScrollPane;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * FocusTraversalProvider for BoxFormBuilder
 * 
 * @author Jose Luis Martin - (jlm@joseluismartin.info)
 */
public class FormFocusTransversalPolicy extends FocusTraversalPolicy {

    private static final Log log = LogFactory.getLog(FormFocusTransversalPolicy.class);
    ArrayList<Component> components = new ArrayList<Component>();

    @Override
    public Component getComponentAfter(Container container, Component component) {

        // Fix awt bug looking for ComboBoxEditor instead ComboBox
        // see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6205817
        if (component.getParent() instanceof JComboBox)
            component = component.getParent();

        int index = components.indexOf(component);

        if (index == -1) { // not owner
            Container childContainer = getTopmostProvider(container, component);
            if (childContainer == null)
                return getFirstComponent(container);

            FocusTraversalPolicy ftp = childContainer.getFocusTraversalPolicy();
            if (ftp != null && ftp != this) {
                Component next = ftp.getComponentAfter(childContainer, component);
                if (next != ftp.getFirstComponent(container))
                    return next;

                // child cycle
                do {
                    index = components.indexOf(childContainer);
                    childContainer = childContainer.getParent();
                } while (index == -1 || childContainer == null);

                if (index == -1) {
                    log.warn("I can't figure what is the next component");
                    return getFirstComponent(container);
                }
            }
        }

        index++;

        if (index < components.size() && index >= 0) {
            Component c = getComponent(index);
            if (c.isEnabled() && c.isFocusable())
                return c;
            else
                return getComponentAfter(container, c);
        }

        return getFirstComponent(container);
    }

    private Component getComponent(int index) {
        Component c = components.get(index);
        Container cc = null;
        if (c instanceof Container) {
            cc = (Container) c;
            if (cc.isFocusTraversalPolicyProvider() || cc.isFocusCycleRoot())
                c = cc.getFocusTraversalPolicy().getFirstComponent(cc);
            else if (cc instanceof JScrollPane) {
                if (((JScrollPane) cc).getViewport().getComponentCount() > 0)
                    c = ((JScrollPane) cc).getViewport().getComponent(0);
            }
        }
        return c != null ? c : cc;
    }

    @Override
    public Component getComponentBefore(Container aContainer, Component aComponent) {

        int index = components.indexOf(aComponent);
        index--;

        if (index < components.size() && index >= 0) {
            Component c = getComponent(index);
            if (c.isEnabled())
                return c;
            else
                return getComponentBefore(aContainer, c);
        }

        return getLastComponent(aContainer);
    }

    @Override
    public Component getDefaultComponent(Container aContainer) {
        if (components.size() > 0) {
            return getComponent(0);
        }

        return null;
    }

    @Override
    public Component getFirstComponent(Container aContainer) {
        return getDefaultComponent(aContainer);
    }

    @Override
    public Component getLastComponent(Container aContainer) {
        if (!components.isEmpty()) {
            Component c = components.get(components.size() - 1);
            if (c.isEnabled())
                return c;
            else
                return getComponentBefore(aContainer, c);
        }

        return null;
    }

    public void add(Component c) {
        components.add(c);
    }

    /**
     * @param component
     * @return
     */
    @SuppressWarnings("unused")
    private FocusTraversalPolicy getFocusTraversalPolicyForComponent(Component component) {
        Container c = null;
        while ((c = component.getParent()) != null) {
            if (c.isFocusTraversalPolicyProvider())
                return c.getFocusTraversalPolicy();
            component = c;
        }

        return null;
    }

    Container getTopmostProvider(Container focusCycleRoot, Component aComponent) {
        Container aCont = aComponent.getParent();
        Container ftp = null;
        while (aCont != focusCycleRoot && aCont != null) {
            if (aCont.isFocusTraversalPolicyProvider()) {
                ftp = aCont;
            }
            aCont = aCont.getParent();
        }
        if (aCont == null) {
            return null;
        }
        return ftp;
    }

}