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

org.jdesktop.layout.MetalLayoutStyle Maven / Gradle / Ivy

Go to download

Swing Layout Extensions goal is to make it easy to create professional cross platform layouts with Swing. This project has an eye towards the needs of GUI builders, such as NetBeans. This project consists of the following pieces: * Ability to get the baseline for components. * Ability to get the preferred gap between components. * A new LayoutManager that utilizes both of these concepts and is tuned toward a free-form drag and drop layout model as can be provided by GUI builders.

There is a newer version: 1.0.2
Show newest version
/*
 * Copyright (C) 2005-2006 Sun Microsystems, Inc. All rights reserved. Use is
 * subject to license terms.
 */ 

package org.jdesktop.layout;

import java.awt.Container;
import javax.swing.ButtonModel;
import javax.swing.DefaultButtonModel;
import javax.swing.JComponent;
import javax.swing.JToggleButton;
import javax.swing.SwingConstants;
import javax.swing.plaf.metal.MetalLookAndFeel;
import javax.swing.plaf.metal.MetalTheme;
import java.lang.reflect.*;

/**
 * An implementation of LayoutStyle for the java look and feel.
 * This information comes from the
 * 
 * The Java Look and Feel Design Guidelines.
 *
 * @version $Revision: 1.7 $
 */
class MetalLayoutStyle extends LayoutStyle {
    /**
     * Whether or not we're using ocean, the default metal theme in 1.5.
     */
    private boolean isOcean;

    public MetalLayoutStyle() {
        isOcean = false;
        try {
            Method method = MetalLookAndFeel.class.
                getMethod("getCurrentTheme", (Class[])null);
            isOcean = ((MetalTheme)method.invoke(null, (Object[])null)).
                      getName() == "Ocean";
        } catch (NoSuchMethodException nsme) {
        } catch (IllegalAccessException iae) {
        } catch (IllegalArgumentException iae2) {
        } catch (InvocationTargetException ite) {
        }
    }

    // NOTE: The JLF makes reference to a number of guidelines in terms of
    // 6 pixels - 1 pixel.  The rationale is because steel buttons have
    // a heavy border followed by a light border, and so that if you pad
    // by 6 pixels it'll look like 7.  Using 5 pixels than produces an effect
    // of 6 pixels.  With Ocean things are different, the only component
    // that you want this behavior to happen with is checkboxs.

    public int getPreferredGap(JComponent source, JComponent target,
                          int type, int position, Container parent) {
        // Invoke super to check arguments.
        super.getPreferredGap(source, target, type, position, parent);

        if (type == INDENT) {
            if (position == SwingConstants.EAST || position == SwingConstants.WEST) {
                int gap = getButtonChildIndent(source, position);
                if (gap != 0) {
                    return gap;
                }
                return 12;
            }
            // Treat vertical INDENT as RELATED
            type = RELATED;
        }
        
        String sourceCID = source.getUIClassID();
        String targetCID = target.getUIClassID();
        int offset;

        if (type == RELATED) {
            if (sourceCID == "ToggleButtonUI" &&
                      targetCID == "ToggleButtonUI") {
                ButtonModel sourceModel = ((JToggleButton)source).getModel();
                ButtonModel targetModel = ((JToggleButton)target).getModel();
                if ((sourceModel instanceof DefaultButtonModel) &&
                    (targetModel instanceof DefaultButtonModel) &&
                    (((DefaultButtonModel)sourceModel).getGroup() ==
                     ((DefaultButtonModel)targetModel).getGroup()) &&
                        ((DefaultButtonModel)sourceModel).getGroup() != null) {
                    // When toggle buttons are exclusive (that is, they form a
                    // radio button set), separate them with 2 pixels. This
                    // rule applies whether the toggle buttons appear in a
                    // toolbar or elsewhere in the interface.
                    // Note: this number does not appear to include any borders
                    // and so is not adjusted by the border of the toggle
                    // button
                    return 2;
                }
                // When toggle buttons are independent (like checkboxes)
                // and used outside a toolbar, separate them with 5
                // pixels.
                if (isOcean) {
                    return 6;
                }
                return 5;
            }
            offset = 6;
        }
        else {
            offset = 12;
        }
        if ((position == SwingConstants.EAST ||
             position == SwingConstants.WEST) &&
            ((sourceCID == "LabelUI" && targetCID != "LabelUI") ||
             (sourceCID != "LabelUI" && targetCID == "LabelUI"))) {
            // Insert 12 pixels between the trailing edge of a
            // label and any associated components. Insert 12
            // pixels between the trailing edge of a label and the
            // component it describes when labels are
            // right-aligned. When labels are left-aligned, insert
            // 12 pixels between the trailing edge of the longest
            // label and its associated component
            return getCBRBPadding(source, target, position, offset + 6);
        }
        return getCBRBPadding(source, target, position, offset);
    }

    int getCBRBPadding(JComponent source, JComponent target, int position,
                       int offset) {
        offset = super.getCBRBPadding(source, target, position, offset);
        if (offset > 0) {
            int buttonAdjustment = getButtonAdjustment(source, position);
            if (buttonAdjustment == 0) {
                buttonAdjustment = getButtonAdjustment(target,
                                                       flipDirection(position));
            }
            offset -= buttonAdjustment;
        }
        if (offset < 0) {
            return 0;
        }
        return offset;
    }

    private int getButtonAdjustment(JComponent source, int edge) {
        String uid = source.getUIClassID();
        if (uid == "ButtonUI" || uid == "ToggleButtonUI") {
            if (!isOcean && (edge == SwingConstants.EAST ||
                             edge == SwingConstants.SOUTH)) {
                return 1;
            }
        }
        else if (edge == SwingConstants.SOUTH) {
            if (uid == "RadioButtonUI" || (!isOcean && uid == "CheckBoxUI")) {
                return 1;
            }
        }
        return 0;
    }

    public int getContainerGap(JComponent component, int position,
            Container parent) {
        super.getContainerGap(component, position, parent);
        // Here's the rules we should be honoring:
        //
        // Include 11 pixels between the bottom and right
        // borders of a dialog box and its command
        // buttons. (To the eye, the 11-pixel spacing appears
        // to be 12 pixels because the white borders on the
        // lower and right edges of the button components are
        // not visually significant.)
        // NOTE: this last text was designed with Steel in mind, not Ocean.
        //
        // Insert 12 pixels between the edges of the panel and the
        // titled border. Insert 11 pixels between the top of the
        // title and the component above the titled border. Insert 12
        // pixels between the bottom of the title and the top of the
        // first label in the panel. Insert 11 pixels between
        // component groups and between the bottom of the last
        // component and the lower border.
        return getCBRBPadding(component, position, 12 -
                getButtonAdjustment(component, position));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy