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

com.jidesoft.swing.JideBorderLayout Maven / Gradle / Ivy

There is a newer version: 3.6.18
Show newest version
/*
 * @(#)JideBorderLayout.java
 *
 * Copyright 2002 JIDE Software Inc. All rights reserved.

 * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package com.jidesoft.swing;

import java.awt.*;

/**
 * This is a modified version of BorderLayout. Different from BorderLayout, the TOP and BOTTOM
 * component's width are same as CENTER component's width. In BorderLayout, their width are the same as the container's
 * width.
 *
 * @see BorderLayout
 */

public class JideBorderLayout implements LayoutManager2,
        java.io.Serializable {
    /**
     * Constructs a border layout with the horizontal gaps between components. The horizontal gap is specified by
     * hgap.
     *
     * @serial
     * @see #getHgap()
     * @see #setHgap(int)
     */
    int hgap;

    /**
     * Constructs a border layout with the vertical gaps between components. The vertical gap is specified by
     * vgap.
     *
     * @serial
     * @see #getVgap()
     * @see #setVgap(int)
     */
    int vgap;

    /**
     * Constant to specify components location to be the north portion of the border layout.
     *
     * @serial
     * @see #getChild(String, boolean)
     * @see #addLayoutComponent
     * @see #getLayoutAlignmentX
     * @see #getLayoutAlignmentY
     * @see #removeLayoutComponent
     */
    Component north;
    /**
     * Constant to specify components location to be the west portion of the border layout.
     *
     * @serial
     * @see #getChild(String, boolean)
     * @see #addLayoutComponent
     * @see #getLayoutAlignmentX
     * @see #getLayoutAlignmentY
     * @see #removeLayoutComponent
     */
    Component west;
    /**
     * Constant to specify components location to be the east portion of the border layout.
     *
     * @serial
     * @see #getChild(String, boolean)
     * @see #addLayoutComponent
     * @see #getLayoutAlignmentX
     * @see #getLayoutAlignmentY
     * @see #removeLayoutComponent
     */
    Component east;
    /**
     * Constant to specify components location to be the south portion of the border layout.
     *
     * @serial
     * @see #getChild(String, boolean)
     * @see #addLayoutComponent
     * @see #getLayoutAlignmentX
     * @see #getLayoutAlignmentY
     * @see #removeLayoutComponent
     */
    Component south;
    /**
     * Constant to specify components location to be the center portion of the border layout.
     *
     * @serial
     * @see #getChild(String, boolean)
     * @see #addLayoutComponent
     * @see #getLayoutAlignmentX
     * @see #getLayoutAlignmentY
     * @see #removeLayoutComponent
     */
    Component center;

    /**
     * A relative positioning constant, that can be used instead of north, south, east, west or center. mixing the two
     * types of constants can lead to unpredictable results.  If you use both types, the relative constants will take
     * precedence. For example, if you add components using both the NORTH and
     * BEFORE_FIRST_LINE constants in a container whose orientation is LEFT_TO_RIGHT, only the
     * BEFORE_FIRST_LINE will be laid out. This will be the same for lastLine, firstItem, lastItem.
     *
     * @serial
     */
    Component firstLine;
    /**
     * A relative positioning constant, that can be used instead of north, south, east, west or center. Please read
     * Description for firstLine.
     *
     * @serial
     */
    Component lastLine;
    /**
     * A relative positioning constant, that can be used instead of north, south, east, west or center. Please read
     * Description for firstLine.
     *
     * @serial
     */
    Component firstItem;
    /**
     * A relative positioning constant, that can be used instead of north, south, east, west or center. Please read
     * Description for firstLine.
     *
     * @serial
     */
    Component lastItem;

    /**
     * The north layout constraint (top of container).
     */
    public static final String NORTH = "North";

    /**
     * The south layout constraint (bottom of container).
     */
    public static final String SOUTH = "South";

    /**
     * The east layout constraint (right side of container).
     */
    public static final String EAST = "East";

    /**
     * The west layout constraint (left side of container).
     */
    public static final String WEST = "West";

    /**
     * The center layout constraint (middle of container).
     */
    public static final String CENTER = "Center";

    /**
     * Synonym for PAGE_START.  Exists for compatibility with previous versions.  PAGE_START is preferred.
     *
     * @see #PAGE_START
     * @since 1.2
     */
    public static final String BEFORE_FIRST_LINE = "First";

    /**
     * Synonym for PAGE_END.  Exists for compatibility with previous versions.  PAGE_END is preferred.
     *
     * @see #PAGE_END
     * @since 1.2
     */
    public static final String AFTER_LAST_LINE = "Last";

    /**
     * Synonym for LINE_START.  Exists for compatibility with previous versions.  LINE_START is preferred.
     *
     * @see #LINE_START
     * @since 1.2
     */
    public static final String BEFORE_LINE_BEGINS = "Before";

    /**
     * Synonym for LINE_END.  Exists for compatibility with previous versions.  LINE_END is preferred.
     *
     * @see #LINE_END
     * @since 1.2
     */
    public static final String AFTER_LINE_ENDS = "After";

    /**
     * The component comes before the first line of the layout's content. For Western, left-to-right and top-to-bottom
     * orientations, this is equivalent to NORTH.
     *
     * @see java.awt.Component#getComponentOrientation
     * @since 1.4
     */
    public static final String PAGE_START = BEFORE_FIRST_LINE;

    /**
     * The component comes after the last line of the layout's content. For Western, left-to-right and top-to-bottom
     * orientations, this is equivalent to SOUTH.
     *
     * @see java.awt.Component#getComponentOrientation
     * @since 1.4
     */
    public static final String PAGE_END = AFTER_LAST_LINE;

    /**
     * The component goes at the beginning of the line direction for the layout. For Western, left-to-right and
     * top-to-bottom orientations, this is equivalent to WEST.
     *
     * @see java.awt.Component#getComponentOrientation
     * @since 1.4
     */
    public static final String LINE_START = BEFORE_LINE_BEGINS;

    /**
     * The component goes at the end of the line direction for the layout. For Western, left-to-right and top-to-bottom
     * orientations, this is equivalent to EAST.
     *
     * @see java.awt.Component#getComponentOrientation
     * @since 1.4
     */
    public static final String LINE_END = AFTER_LINE_ENDS;

    /*
     * JDK 1.1 serialVersionUID
     */
    private static final long serialVersionUID = -8658291919501921765L;

    /**
     * Constructs a new border layout with no gaps between components.
     */
    public JideBorderLayout() {
        this(0, 0);
    }

    /**
     * Constructs a border layout with the specified gaps between components. The horizontal gap is specified by
     * hgap and the vertical gap is specified by vgap.
     *
     * @param hgap the horizontal gap.
     * @param vgap the vertical gap.
     */
    public JideBorderLayout(int hgap, int vgap) {
        this.hgap = hgap;
        this.vgap = vgap;
    }

    /**
     * Returns the horizontal gap between components.
     *
     * @since JDK1.1
     */
    public int getHgap() {
        return hgap;
    }

    /**
     * Sets the horizontal gap between components.
     *
     * @param hgap the horizontal gap between components
     * @since JDK1.1
     */
    public void setHgap(int hgap) {
        this.hgap = hgap;
    }

    /**
     * Returns the vertical gap between components.
     *
     * @since JDK1.1
     */
    public int getVgap() {
        return vgap;
    }

    /**
     * Sets the vertical gap between components.
     *
     * @param vgap the vertical gap between components
     * @since JDK1.1
     */
    public void setVgap(int vgap) {
        this.vgap = vgap;
    }

    /**
     * Adds the specified component to the layout, using the specified constraint object.  For border layouts, the
     * constraint must be one of the following constants:  NORTH, SOUTH, EAST,
     * WEST, or CENTER.
     * 

* Most applications do not call this method directly. This method is called when a component is added to a * container using the Container.add method with the same argument types. * * @param comp the component to be added. * @param constraints an object that specifies how and where the component is added to the layout. * @throws IllegalArgumentException if the constraint object is not a string, or if it not one of the five specified * constants. * @see java.awt.Container#add(java.awt.Component, java.lang.Object) * @since JDK1.1 */ public void addLayoutComponent(Component comp, Object constraints) { synchronized (comp.getTreeLock()) { if ((constraints == null) || (constraints instanceof String)) { addLayoutComponent((String) constraints, comp); } else { throw new IllegalArgumentException("cannot add to layout: constraint must be a string (or null)"); } } } /** * @deprecated replaced by addLayoutComponent(Component, Object). */ @Deprecated public void addLayoutComponent(String name, Component comp) { synchronized (comp.getTreeLock()) { /* Special case: treat null the same as "Center". */ if (name == null) { name = "Center"; } /* Assign the component to one of the known regions of the layout. */ if ("Center".equals(name)) { center = comp; } else if ("North".equals(name)) { north = comp; } else if ("South".equals(name)) { south = comp; } else if ("East".equals(name)) { east = comp; } else if ("West".equals(name)) { west = comp; } else if (BEFORE_FIRST_LINE.equals(name)) { firstLine = comp; } else if (AFTER_LAST_LINE.equals(name)) { lastLine = comp; } else if (BEFORE_LINE_BEGINS.equals(name)) { firstItem = comp; } else if (AFTER_LINE_ENDS.equals(name)) { lastItem = comp; } else { throw new IllegalArgumentException("cannot add to layout: unknown constraint: " + name); } } } /** * Removes the specified component from this border layout. This method is called when a container calls its * remove or removeAll methods. Most applications do not call this method directly. * * @param comp the component to be removed. * @see java.awt.Container#remove(java.awt.Component) * @see java.awt.Container#removeAll() */ public void removeLayoutComponent(Component comp) { synchronized (comp.getTreeLock()) { if (comp == center) { center = null; } else if (comp == north) { north = null; } else if (comp == south) { south = null; } else if (comp == east) { east = null; } else if (comp == west) { west = null; } if (comp == firstLine) { firstLine = null; } else if (comp == lastLine) { lastLine = null; } else if (comp == firstItem) { firstItem = null; } else if (comp == lastItem) { lastItem = null; } } } /** * Gets the component that was added using the given constraint * * @param constraints the desired constraint, one of CENTER, NORTH, SOUTH, * WEST, EAST, PAGE_START, PAGE_END, * LINE_START, LINE_END * @return the component at the given location, or null if the location is empty * * @throws IllegalArgumentException if the constraint object is not one of the nine specified constants * @see #addLayoutComponent(java.awt.Component, java.lang.Object) * @since 1.5 */ public Component getLayoutComponent(Object constraints) { if (CENTER.equals(constraints)) { return center; } else if (NORTH.equals(constraints)) { return north; } else if (SOUTH.equals(constraints)) { return south; } else if (WEST.equals(constraints)) { return west; } else if (EAST.equals(constraints)) { return east; } else if (PAGE_START.equals(constraints)) { return firstLine; } else if (PAGE_END.equals(constraints)) { return lastLine; } else if (LINE_START.equals(constraints)) { return firstItem; } else if (LINE_END.equals(constraints)) { return lastItem; } else { throw new IllegalArgumentException("cannot get component: unknown constraint: " + constraints); } } /** * Returns the component that corresponds to the given constraint location based on the target * Container's component orientation. Components added with the relative constraints * PAGE_START, PAGE_END, LINE_START, and LINE_END take * precedence over components added with the explicit constraints NORTH, SOUTH, * WEST, and EAST. The Container's component orientation is used to determine * the location of components added with LINE_START and LINE_END. * * @param constraints the desired absolute position, one of CENTER, NORTH, * SOUTH, EAST, WEST * @param target the {@code Container} used to obtain the constraint location based on the target {@code * Container}'s component orientation. * @return the component at the given location, or null if the location is empty * * @throws IllegalArgumentException if the constraint object is not one of the five specified constants * @throws NullPointerException if the target parameter is null * @see #addLayoutComponent(java.awt.Component, java.lang.Object) * @since 1.5 */ public Component getLayoutComponent(Container target, Object constraints) { boolean ltr = target.getComponentOrientation().isLeftToRight(); Component result = null; if (NORTH.equals(constraints)) { result = (firstLine != null) ? firstLine : north; } else if (SOUTH.equals(constraints)) { result = (lastLine != null) ? lastLine : south; } else if (WEST.equals(constraints)) { result = ltr ? firstItem : lastItem; if (result == null) { result = west; } } else if (EAST.equals(constraints)) { result = ltr ? lastItem : firstItem; if (result == null) { result = east; } } else if (CENTER.equals(constraints)) { result = center; } else { throw new IllegalArgumentException("cannot get component: invalid constraint: " + constraints); } return result; } /** * Gets the constraints for the specified component * * @param comp the component to be queried * @return the constraint for the specified component, or null if component is null or is not present in this * layout * * @see #addLayoutComponent(java.awt.Component, java.lang.Object) * @since 1.5 */ public Object getConstraints(Component comp) { //fix for 6242148 : API method java.awt.BorderLayout.getConstraints(null) should return null if (comp == null) { return null; } if (comp == center) { return CENTER; } else if (comp == north) { return NORTH; } else if (comp == south) { return SOUTH; } else if (comp == west) { return WEST; } else if (comp == east) { return EAST; } else if (comp == firstLine) { return PAGE_START; } else if (comp == lastLine) { return PAGE_END; } else if (comp == firstItem) { return LINE_START; } else if (comp == lastItem) { return LINE_END; } return null; } /** * Determines the minimum size of the target container using this layout manager. *

* This method is called when a container calls its getMinimumSize method. Most applications do not * call this method directly. * * @param target the container in which to do the layout. * @return the minimum dimensions needed to lay out the subcomponents of the specified container. * * @see java.awt.Container * @see java.awt.BorderLayout#preferredLayoutSize * @see java.awt.Container#getMinimumSize() */ public Dimension minimumLayoutSize(Container target) { synchronized (target.getTreeLock()) { Dimension dim = new Dimension(0, 0); boolean ltr = target.getComponentOrientation().isLeftToRight(); Component c = null; if ((c = getChild(CENTER, ltr)) != null) { Dimension d = c.getMinimumSize(); dim.width += d.width; dim.height = Math.max(d.height, dim.height); } if ((c = getChild(NORTH, ltr)) != null) { Dimension d = c.getMinimumSize(); dim.width = Math.max(d.width, dim.width); dim.height += d.height + vgap; } if ((c = getChild(SOUTH, ltr)) != null) { Dimension d = c.getMinimumSize(); dim.width = Math.max(d.width, dim.width); dim.height += d.height + vgap; } if ((c = getChild(EAST, ltr)) != null) { Dimension d = c.getMinimumSize(); dim.width += d.width + hgap; dim.height = Math.max(d.height, dim.height); } if ((c = getChild(WEST, ltr)) != null) { Dimension d = c.getMinimumSize(); dim.width += d.width + hgap; dim.height = Math.max(d.height, dim.height); } Insets insets = target.getInsets(); dim.width += insets.left + insets.right; dim.height += insets.top + insets.bottom; return dim; } } /** * Determines the preferred size of the target container using this layout manager, based on the * components in the container. *

* Most applications do not call this method directly. This method is called when a container calls its * getPreferredSize method. * * @param target the container in which to do the layout. * @return the preferred dimensions to lay out the subcomponents of the specified container. * * @see java.awt.Container * @see java.awt.BorderLayout#minimumLayoutSize * @see java.awt.Container#getPreferredSize() */ public Dimension preferredLayoutSize(Container target) { synchronized (target.getTreeLock()) { Dimension dim = new Dimension(0, 0); boolean ltr = target.getComponentOrientation().isLeftToRight(); Component c = null; if ((c = getChild(CENTER, ltr)) != null) { Dimension d = c.getPreferredSize(); dim.width += d.width; dim.height = Math.max(d.height, dim.height); } if ((c = getChild(NORTH, ltr)) != null) { Dimension d = c.getPreferredSize(); dim.width = Math.max(d.width, dim.width); dim.height += d.height + vgap; } if ((c = getChild(SOUTH, ltr)) != null) { Dimension d = c.getPreferredSize(); dim.width = Math.max(d.width, dim.width); dim.height += d.height + vgap; } if ((c = getChild(EAST, ltr)) != null) { Dimension d = c.getPreferredSize(); dim.width += d.width + hgap; dim.height = Math.max(d.height, dim.height); } if ((c = getChild(WEST, ltr)) != null) { Dimension d = c.getPreferredSize(); dim.width += d.width + hgap; dim.height = Math.max(d.height, dim.height); } Insets insets = target.getInsets(); dim.width += insets.left + insets.right; dim.height += insets.top + insets.bottom; return dim; } } /** * 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 */ public Dimension maximumLayoutSize(Container target) { return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); } /** * Returns the alignment along the x axis. This specifies how the component would like to be aligned relative to * other components. The value should be a number between 0 and 1 where 0 represents alignment along the origin, 1 * is aligned the furthest away from the origin, 0.5 is centered, etc. */ public float getLayoutAlignmentX(Container parent) { return 0.5f; } /** * Returns the alignment along the y axis. This specifies how the component would like to be aligned relative to * other components. The value should be a number between 0 and 1 where 0 represents alignment along the origin, 1 * is aligned the furthest away from the origin, 0.5 is centered, etc. */ public float getLayoutAlignmentY(Container parent) { return 0.5f; } /** * Invalidates the layout, indicating that if the layout manager has cached information it should be discarded. */ public void invalidateLayout(Container target) { } /** * Lays out the container argument using this border layout. *

* This method actually reshapes the components in the specified container in order to satisfy the constraints of * this BorderLayout object. The NORTH and SOUTH components, if any, are * placed at the top and bottom of the container, respectively. The WEST and EAST * components are then placed on the left and right, respectively. Finally, the CENTER object is placed * in any remaining space in the middle. *

* Most applications do not call this method directly. This method is called when a container calls its * doLayout method. * * @param target the container in which to do the layout. * @see java.awt.Container * @see java.awt.Container#doLayout() */ public void layoutContainer(Container target) { synchronized (target.getTreeLock()) { Insets insets = target.getInsets(); int top = insets.top; int bottom = target.getHeight() - insets.bottom; int left = insets.left; int right = target.getWidth() - insets.right; boolean ltr = target.getComponentOrientation().isLeftToRight(); Component north = getChild(NORTH, ltr); Component south = getChild(SOUTH, ltr); Component east = getChild(EAST, ltr); Component west = getChild(WEST, ltr); Component center = getChild(CENTER, ltr); /* * Include the hgap here since if the east or west components * do not exist then there should be no gap applied */ int westGap = (west != null ? west.getPreferredSize().width + hgap : 0); int eastGap = (east != null ? east.getPreferredSize().width + hgap : 0); if (north != null) { // north.setSize(right - left - westGap - eastGap/* - 2 * hgap*/, north.getHeight()); Dimension d = north.getPreferredSize(); north.setBounds(left + westGap/* + hgap*/, top, right - left - westGap - eastGap/* - 2 * hgap*/, d.height); top += d.height + vgap; } if (south != null) { // south.setSize(right - left - westGap - eastGap/* - 2 * hgap*/, south.getHeight()); Dimension d = south.getPreferredSize(); south.setBounds(left + westGap/* + hgap*/, bottom - d.height, right - left - westGap - eastGap/* - 2 * hgap*/, d.height); bottom -= d.height + vgap; } if (east != null) { east.setSize(east.getWidth(), bottom - top); Dimension d = east.getPreferredSize(); east.setBounds(right - d.width, top, d.width, bottom - top); right -= d.width + hgap; } if (west != null) { west.setSize(west.getWidth(), bottom - top); Dimension d = west.getPreferredSize(); west.setBounds(left, top, d.width, bottom - top); left += d.width + hgap; } if (center != null) { center.setBounds(left, top, right - left, bottom - top); } } } /** * Get the component that corresponds to the given constraint location * * @param key The desired absolute position, either NORTH, SOUTH, EAST, or WEST. * @param ltr Is the component line direction left-to-right? */ private Component getChild(String key, boolean ltr) { Component result = null; if (key == NORTH) { result = (firstLine != null) ? firstLine : north; } else if (key == SOUTH) { result = (lastLine != null) ? lastLine : south; } else if (key == WEST) { result = ltr ? firstItem : lastItem; if (result == null) { result = west; } } else if (key == EAST) { result = ltr ? lastItem : firstItem; if (result == null) { result = east; } } else if (key == CENTER) { result = center; } if (result != null && !result.isVisible()) { result = null; } return result; } /** * Returns a string representation of the state of this border layout. * * @return a string representation of this border layout. */ public String toString() { return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + "]"; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy