All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nuiton.jaxx.runtime.swing.CardLayout2 Maven / Gradle / Ivy

There is a newer version: 3.0-alpha-6
Show newest version
/*
 * #%L
 * JAXX :: Runtime
 * %%
 * Copyright (C) 2008 - 2017 CodeLutin
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as 
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public 
 * License along with this program.  If not, see
 * .
 * #L%
 */
package org.nuiton.jaxx.runtime.swing;

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

import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;

/**
 * An override of the awt {@link CardLayout}.
 *
 * Because in the original layout is not overridable : everything is package level accessible.
 *
 * This new class offers to test if a constrains (as a Serializable) is actually dealed by the layout,
 * via the method {@link #contains(Serializable)}.
 *
 * We had also another method to obtain the current visible component in a container layouted by the class,
 * via the method {@link #getVisibleComponent(Container)}.
 *
 * @author Tony Chemit - [email protected]
 * @version 1.0
 */
public class CardLayout2 extends CardLayout {

    /** log */
    static private final Log log = LogFactory.getLog(CardLayout2.class);

    private static final long serialVersionUID = 1L;

    /** list of already loaded context (since the {@link #vector} attribute is package visible... */
    protected final List contexts = new LinkedList<>();

    /**
     * A flag to compute dimension only on visible component.
     *
     * This is usefull when we only care of the visible component.
     */
    protected boolean useOnlyVisibleComponentDimension;

    @Override
    public void addLayoutComponent(Component comp, Object constraints) {
        super.addLayoutComponent(comp, constraints);
        contexts.remove(constraints);
        contexts.add((Serializable) constraints);
        if (log.isDebugEnabled()) {
            log.debug(this + " new constraints : " + constraints);
        }
    }

    public void removeLayoutComponent(Component comp, Serializable constraints) {
        removeLayoutComponent(comp);
        contexts.remove(constraints);
    }

    /**
     * Test if a constrains is contained in the layout.
     *
     * @param constraints l'identifiant a tester
     * @return {@code true} si l'identifiant est deja present dans le
     * layout, {@code false} otherwise.
     */
    public boolean contains(Serializable constraints) {
        return contexts.contains(constraints);
    }

    /**
     * Obtain the visible component in the container.
     *
     * @param container the container using this layout
     * @return the component visible in the container.
     */
    public Component getVisibleComponent(Container container) {
        checkContainer(container);
        for (Component component : container.getComponents()) {
            if (component.isVisible()) {
                return component;
            }
        }
        // no component actually visible
        return null;
    }

    public Component getComponent(Container container, String constraints) {
        checkContainer(container);
        checkConstraints(constraints);
        int index = contexts.indexOf(constraints);
        return container.getComponents()[index];
    }

    /**
     * Determines the preferred size of the container argument using
     * this card layout.
     *
     * @param parent the parent container in which to do the layout
     * @return the preferred dimensions to lay out the subcomponents
     * of the specified container
     * @see Container#getPreferredSize
     * @see CardLayout#minimumLayoutSize
     */
    @Override
    public Dimension preferredLayoutSize(Container parent) {
        Dimension dimension = null;
        if (useOnlyVisibleComponentDimension) {
            Component comp = getVisibleComponent(parent);
            if (comp != null) {
                dimension = comp.getPreferredSize();
            }
        }
        if (dimension == null) {
            dimension = super.preferredLayoutSize(parent);
        }
        return dimension;
    }

    /**
     * Calculates the minimum size for the specified panel.
     *
     * @param parent the parent container in which to do the layout
     * @return the minimum dimensions required to lay out the
     * subcomponents of the specified container
     * @see Container#doLayout
     * @see CardLayout#preferredLayoutSize
     */
    @Override
    public Dimension minimumLayoutSize(Container parent) {
        Dimension dimension = null;
        if (useOnlyVisibleComponentDimension) {
            Component comp = getVisibleComponent(parent);
            if (comp != null) {
                dimension = comp.getMinimumSize();
            }
        }
        if (dimension == null) {
            dimension = super.minimumLayoutSize(parent);
        }
        return dimension;
    }

    /**
     * Returns the maximum dimensions for this layout given the components
     * in the specified target container.
     *
     * @param target the component which needs to be laid out
     * @see Container
     * @see #minimumLayoutSize
     * @see #preferredLayoutSize
     */
    @Override
    public Dimension maximumLayoutSize(Container target) {
        Dimension dimension = null;
        if (useOnlyVisibleComponentDimension) {
            Component comp = getVisibleComponent(target);
            if (comp != null) {
                dimension = comp.getMaximumSize();
            }
        }
        if (dimension == null) {
            dimension = super.maximumLayoutSize(target);
        }
        return dimension;
    }

    /**
     * Lays out the specified container using this card layout.
     *
     * Each component in the parent container is reshaped
     * to be the size of the container, minus space for surrounding
     * insets, horizontal gaps, and vertical gaps.
     *
     * @param parent the parent container in which to do the layout
     * @see Container#doLayout
     */
    @Override
    public void layoutContainer(Container parent) {
        if (useOnlyVisibleComponentDimension) {
            Component comp = getVisibleComponent(parent);
            if (comp != null) {
                //dimension = comp.getMinimumSize();
                Insets insets = parent.getInsets();
                comp.setBounds(getHgap() + insets.left, getVgap() + insets.top,
                               parent.getWidth() - (getHgap() * 2 + insets.left + insets.right),
                               parent.getHeight() - (getVgap() * 2 + insets.top + insets.bottom));
            } else {
                super.layoutContainer(parent);
            }
        } else {
            super.layoutContainer(parent);
        }
    }

    public boolean isUseOnlyVisibleComponentDimension() {
        return useOnlyVisibleComponentDimension;
    }

    public void setUseOnlyVisibleComponentDimension(boolean useOnlyVisibleComponentDimension) {
        this.useOnlyVisibleComponentDimension = useOnlyVisibleComponentDimension;
    }

    /**
     * remove from cardlayout and linked container all his components.
     *
     * @param parent the parent container linked with the layout
     */
    public void reset(Container parent) {
        checkContainer(parent);
        for (Component component : parent.getComponents()) {
            removeLayoutComponent(component);
            parent.remove(component);
        }
        contexts.clear();

    }

    protected void checkContainer(Container container) {
        if (!equals(container.getLayout())) {
            throw new IllegalArgumentException("the container is not managed by the current layout");
        }
    }

    protected void checkConstraints(String constraints) {
        if (!contains(constraints)) {
            throw new IllegalArgumentException("the constraints '" + constraints + "' is not supported by this layout : " + contexts);
        }
    }

    public Serializable[] getContexts() {
        return contexts.toArray(new Serializable[contexts.size()]);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy