📄 grouplayout.java
字号:
/*
* Copyright (C) 2005-2006 Sun Microsystems, Inc. All rights reserved. Use is
* subject to license terms.
*/
package org.jdesktop.layout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager2;
import javax.swing.SwingConstants;
import javax.swing.JComponent;
import java.util.*;
/**
* GroupLayout is a LayoutManager that hierarchically groups components to
* achieve common, and not so common, layouts. Grouping is done by instances
* of the Group class. GroupLayout supports two types of groups:
* <table>
* <tr><td valign=top>Sequential:<td>A sequential group positions its child
* elements sequentially, one after another.
* <tr><td valign=top>Parallel:<td>A parallel group positions its child
* elements in the same space on top of each other. Parallel groups
* can also align the child elements along their baseline.
* </table>
* Each Group can contain any number of child groups, Components or gaps.
* GroupLayout treats each axis independently. That is, there is a group
* representing the horizontal axis, and a separate group representing the
* vertical axis. The horizontal group is responsible for setting the x
* and width of its contents, where as the vertical group is responsible for
* setting the y and height of its contents.
* <p>
* The following code builds a simple layout consisting of two labels in
* one column, followed by two textfields in the next column:
* <pre>
* JComponent panel = ...;
* GroupLayout layout = new GroupLayout(panel);
* panel.setLayout(layout);
* layout.setAutocreateGaps(true);
* layout.setAutocreateContainerGaps(true);
* GroupLayout.SequentialGroup hGroup = layout.createSequentialGroup();
* hGroup.add(layout.createParallelGroup().add(label1).add(label2)).
* add(layout.createParallelGroup().add(tf1).add(tf2));
* layout.setHorizontalGroup(hGroup);
* GroupLayout.SequentialGroup vGroup = layout.createSequentialGroup();
* vGroup.add(layout.createParallelGroup(GroupLayout.BASELINE).add(label1).add(tf1)).
* add(layout.createParallelGroup(GroupLayout.BASELINE).add(label2).add(tf2));
* layout.setVerticalGroup(vGroup);
* </pre>
* <p>
* This layout consists of the following:
* <ul><li>The horizontal axis consists of a sequential group containing two
* parallel groups. The first parallel group consists of the labels,
* with the second parallel group consisting of the text fields.
* <li>The vertical axis similarly consists of a sequential group
* containing two parallel groups. The parallel groups align their
* contents along the baseline. The first parallel group consists
* of the first label and text field, and the second group consists
* of the second label and text field.
* </ul>
* There are a couple of things to notice in this code:
* <ul>
* <li>You need not explicitly add the components to the container, this
* is indirectly done by using one of the <code>add</code> methods.
* <li>The various <code>add</code> methods of <code>Groups</code> return
* themselves. This allows for easy chaining of invocations. For
* example, <code>group.add(label1).add(label2);</code> is equivalent to
* <code>group.add(label1);group.add(label2);</code>.
* <li>There are no public constructors for the Groups, instead
* use the create methods of <code>GroupLayout</code>.
* </ul>
* GroupLayout offer the ability to automatically insert the appropriate gap
* between components. This can be turned on using the
* <code>setAutocreateGaps()</code> method. Similarly you can use
* the <code>setAutocreateContainerGaps()</code> method to insert gaps
* between the components and the container.
*
* @version $Revision: 1.1 $
* @author Tomas Pavek
* @author Jan Stola
* @author Scott Violet
*/
public class GroupLayout implements LayoutManager2 {
// Used in size calculations
private static final int MIN_SIZE = 0;
private static final int PREF_SIZE = 1;
private static final int MAX_SIZE = 2;
// Used by prepare, indicates min, pref or max isn't going to be used.
private static final int SPECIFIC_SIZE = 3;
private static final int UNSET = Integer.MIN_VALUE;
/**
* Possible argument when linking sizes of components. Specifies the
* the two component should share the same size along the horizontal
* axis.
*
* @see #linkSize(java.awt.Component[],int)
*/
public static final int HORIZONTAL = 1;
/**
* Possible argument when linking sizes of components. Specifies the
* the two component should share the same size along the vertical
* axis.
*
* @see #linkSize(java.awt.Component[],int)
*/
public static final int VERTICAL = 2;
private static final int NO_ALIGNMENT = 0;
/**
* Possible alignment type. Indicates the elements should be
* aligned to the origin. For the horizontal axis with a left to
* right orientation this means aligned to the left.
*
* @see #createParallelGroup(int)
*/
public static final int LEADING = 1;
/**
* Possible alignment type. Indicates the elements should be
* aligned to the end. For the horizontal axis with a left to
* right orientation this means aligned to the right.
*
* @see #createParallelGroup(int)
*/
public static final int TRAILING = 2;
/**
* Possible alignment type. Indicates the elements should centered in
* the spaced provided.
*
* @see #createParallelGroup(int)
*/
public static final int CENTER = 4;
/**
* Possible alignment type. Indicates the elements should aligned along
* their baseline.
*
* @see #createParallelGroup(int)
*/
public static final int BASELINE = 3;
/**
* Possible value for the add methods that takes a Component.
* Indicates the size from the component should be used.
*/
public static final int DEFAULT_SIZE = -1;
/**
* Possible value for the add methods that takes a Component.
* Indicates the preferred size should be used.
*/
public static final int PREFERRED_SIZE = -2;
// Whether or not we automatically try and create the preferred
// padding between components.
private boolean autocreatePadding;
// Whether or not we automatically try and create the preferred
// padding between containers
private boolean autocreateContainerPadding;
/**
* Group responsible for layout along the horizontal axis. This is NOT
* the user specified group, use getHorizontalGroup to dig that out.
*/
private Group horizontalGroup;
/**
* Group responsible for layout along the vertical axis. This is NOT
* the user specified group, use getVerticalGroup to dig that out.
*/
private Group verticalGroup;
// Maps from Component to ComponentInfo. This is used for tracking
// information specific to a Component.
private Map componentInfos;
// Container we're doing layout for.
private Container host;
// Used by areParallelSiblings, cached to avoid excessive garbage.
private Set tmpParallelSet;
// Indicates Springs have changed in some way since last change.
private boolean springsChanged;
// Indicates invalidateLayout has been invoked.
private boolean isValid;
// Whether or not any preferred padding (or container padding) springs exist
private boolean hasPreferredPaddingSprings;
/**
* The LayoutStyle instance to use, if null the sharedInstance is used.
*/
private LayoutStyle layoutStyle;
/**
* If true, components that are not visible are treated as though they
* aren't there.
*/
private boolean honorsVisibility;
private static void checkSize(int min, int pref, int max,
boolean isComponentSpring) {
checkResizeType(min, isComponentSpring);
if (!isComponentSpring && pref < 0) {
throw new IllegalArgumentException("Pref must be >= 0");
} else if (isComponentSpring) {
checkResizeType(pref, true);
}
checkResizeType(max, isComponentSpring);
checkLessThan(min, pref);
checkLessThan(pref, max);
}
private static void checkResizeType(int type, boolean isComponentSpring) {
if (type < 0 && ((isComponentSpring && type != DEFAULT_SIZE &&
type != PREFERRED_SIZE) ||
(!isComponentSpring && type != PREFERRED_SIZE))) {
throw new IllegalArgumentException("Invalid size");
}
}
private static void checkLessThan(int min, int max) {
if (min >= 0 && max >= 0 && min > max) {
throw new IllegalArgumentException(
"Following is not met: min<=pref<=max");
}
}
/**
* Creates a GroupLayout for the specified JComponent.
*
* @param host the Container to layout
* @throws IllegalArgumentException if host is null
*/
public GroupLayout(Container host) {
if (host == null) {
throw new IllegalArgumentException("Container must be non-null");
}
honorsVisibility = true;
this.host = host;
setHorizontalGroup(createParallelGroup(LEADING, true));
setVerticalGroup(createParallelGroup(LEADING, true));
componentInfos = new HashMap();
tmpParallelSet = new HashSet();
}
/**
* Sets whether component visiblity is considered when sizing and
* positioning components. A value of <code>true</code> indicates that
* non-visible components should not be treated as part of the
* layout. A value of <code>false</code> indicates that components should be
* positioned and sized regardless of visibility.
* <p>
* A value of <code>false</code> is useful when the visibility of components
* is dynamically adjusted and you don't want surrounding components and
* the sizing to change.
* <p>
* The specified value is used for components that do not have an
* explicit visibility specified.
* <p>
* The default is <code>true</code>.
*
* @param honorsVisibility whether component visiblity is considered when
* sizing and positioning components
* @see #setHonorsVisibility(Component,Boolean)
*/
public void setHonorsVisibility(boolean honorsVisibility) {
if (this.honorsVisibility != honorsVisibility) {
this.honorsVisibility = honorsVisibility;
springsChanged = true;
isValid = false;
invalidateHost();
}
}
/**
* Returns whether component visiblity is considered when sizing and
* positioning components.
*
* @return whether component visiblity is considered when sizing and
* positioning components
*/
public boolean getHonorsVisibility() {
return honorsVisibility;
}
/**
* Sets whether the component's visiblity is considered for
* sizing and positioning. A value of <code>Boolean.TRUE</code>
* indicates that if <code>component</code> is not visible it should
* not be treated as part of the layout. A value of <code>false</code>
* indicates that <code>component</code> is positioned and sized
* regardless of it's visibility. A value of <code>null</code>
* indicates the value specified by the single argument method <code>
* setHonorsVisibility</code> should be used.
* <p>
* If <code>component</code> is not a child of the <code>Container</code> this
* <code>GroupLayout</code> is managing, it will be added to the
* <code>Container</code>.
*
* @param component the component
* @param honorsVisibility whether <code>component</code>'s visiblity should be
* considered for sizing and positioning
* @throws IllegalArgumentException if <code>component</code> is <code>null</code>
* @see #setHonorsVisibility(boolean)
*/
public void setHonorsVisibility(Component component,
Boolean honorsVisibility) {
if (component == null) {
throw new IllegalArgumentException("Component must be non-null");
}
getComponentInfo(component).setHonorsVisibility(honorsVisibility);
springsChanged = true;
isValid = false;
invalidateHost();
}
/**
* Returns a textual description of this GroupLayout. The return value
* is intended for debugging purposes only.
*
* @return textual description of this GroupLayout
**/
public String toString() {
if (springsChanged) {
registerComponents(horizontalGroup, HORIZONTAL);
registerComponents(verticalGroup, VERTICAL);
}
StringBuffer buffer = new StringBuffer();
buffer.append("HORIZONTAL\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -