260 lines
9.1 KiB
Java
260 lines
9.1 KiB
Java
/*
|
|
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation. Oracle designates this
|
|
* particular file as subject to the "Classpath" exception as provided
|
|
* by Oracle in the LICENSE file that accompanied this code.
|
|
*
|
|
* This code 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 Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*/
|
|
package sun.swing;
|
|
|
|
import java.awt.Container;
|
|
import java.awt.Insets;
|
|
import javax.swing.*;
|
|
import javax.swing.LayoutStyle.ComponentPlacement;
|
|
import javax.swing.border.Border;
|
|
import javax.swing.plaf.UIResource;
|
|
|
|
/**
|
|
* An implementation of <code>LayoutStyle</code> that returns 6 for related
|
|
* components, otherwise 12. This class also provides helper methods for
|
|
* subclasses.
|
|
*
|
|
*/
|
|
public class DefaultLayoutStyle extends LayoutStyle {
|
|
private static final DefaultLayoutStyle INSTANCE =
|
|
new DefaultLayoutStyle();
|
|
|
|
public static LayoutStyle getInstance() {
|
|
return INSTANCE;
|
|
}
|
|
|
|
@Override
|
|
public int getPreferredGap(JComponent component1, JComponent component2,
|
|
ComponentPlacement type, int position, Container parent) {
|
|
if (component1 == null || component2 == null || type == null) {
|
|
throw new NullPointerException();
|
|
}
|
|
|
|
checkPosition(position);
|
|
|
|
if (type == ComponentPlacement.INDENT &&
|
|
(position == SwingConstants.EAST ||
|
|
position == SwingConstants.WEST)) {
|
|
int indent = getIndent(component1, position);
|
|
if (indent > 0) {
|
|
return indent;
|
|
}
|
|
}
|
|
return (type == ComponentPlacement.UNRELATED) ? 12 : 6;
|
|
}
|
|
|
|
@Override
|
|
public int getContainerGap(JComponent component, int position,
|
|
Container parent) {
|
|
if (component == null) {
|
|
throw new NullPointerException();
|
|
}
|
|
checkPosition(position);
|
|
return 6;
|
|
}
|
|
|
|
/**
|
|
* Returns true if the classes identify a JLabel and a non-JLabel
|
|
* along the horizontal axis.
|
|
*/
|
|
protected boolean isLabelAndNonlabel(JComponent c1, JComponent c2,
|
|
int position) {
|
|
if (position == SwingConstants.EAST ||
|
|
position == SwingConstants.WEST) {
|
|
boolean c1Label = (c1 instanceof JLabel);
|
|
boolean c2Label = (c2 instanceof JLabel);
|
|
return ((c1Label || c2Label) && (c1Label != c2Label));
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* For some look and feels check boxs and radio buttons typically
|
|
* don't paint the border, yet they have padding for a border. Look
|
|
* and feel guidelines generally don't include this space. Use
|
|
* this method to subtract this space from the specified
|
|
* components.
|
|
*
|
|
* @param source First component
|
|
* @param target Second component
|
|
* @param position Position doing layout along.
|
|
* @param offset Ideal offset, not including border/margin
|
|
* @return offset - border/margin around the component.
|
|
*/
|
|
protected int getButtonGap(JComponent source, JComponent target,
|
|
int position, int offset) {
|
|
offset -= getButtonGap(source, position);
|
|
if (offset > 0) {
|
|
offset -= getButtonGap(target, flipDirection(position));
|
|
}
|
|
if (offset < 0) {
|
|
return 0;
|
|
}
|
|
return offset;
|
|
}
|
|
|
|
/**
|
|
* For some look and feels check boxs and radio buttons typically
|
|
* don't paint the border, yet they have padding for a border. Look
|
|
* and feel guidelines generally don't include this space. Use
|
|
* this method to subtract this space from the specified
|
|
* components.
|
|
*
|
|
* @param source Component
|
|
* @param position Position doing layout along.
|
|
* @param offset Ideal offset, not including border/margin
|
|
* @return offset - border/margin around the component.
|
|
*/
|
|
protected int getButtonGap(JComponent source, int position, int offset) {
|
|
offset -= getButtonGap(source, position);
|
|
return Math.max(offset, 0);
|
|
}
|
|
|
|
/**
|
|
* If <code>c</code> is a check box or radio button, and the border is
|
|
* not painted this returns the inset along the specified axis.
|
|
*/
|
|
public int getButtonGap(JComponent c, int position) {
|
|
String classID = c.getUIClassID();
|
|
if ((classID == "CheckBoxUI" || classID == "RadioButtonUI") &&
|
|
!((AbstractButton)c).isBorderPainted()) {
|
|
Border border = c.getBorder();
|
|
if (border instanceof UIResource) {
|
|
return getInset(c, position);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
private void checkPosition(int position) {
|
|
if (position != SwingConstants.NORTH &&
|
|
position != SwingConstants.SOUTH &&
|
|
position != SwingConstants.WEST &&
|
|
position != SwingConstants.EAST) {
|
|
throw new IllegalArgumentException();
|
|
}
|
|
}
|
|
|
|
protected int flipDirection(int position) {
|
|
switch(position) {
|
|
case SwingConstants.NORTH:
|
|
return SwingConstants.SOUTH;
|
|
case SwingConstants.SOUTH:
|
|
return SwingConstants.NORTH;
|
|
case SwingConstants.EAST:
|
|
return SwingConstants.WEST;
|
|
case SwingConstants.WEST:
|
|
return SwingConstants.EAST;
|
|
}
|
|
assert false;
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Returns the amount to indent the specified component if it's
|
|
* a JCheckBox or JRadioButton. If the component is not a JCheckBox or
|
|
* JRadioButton, 0 will be returned.
|
|
*/
|
|
protected int getIndent(JComponent c, int position) {
|
|
String classID = c.getUIClassID();
|
|
if (classID == "CheckBoxUI" || classID == "RadioButtonUI") {
|
|
AbstractButton button = (AbstractButton)c;
|
|
Insets insets = c.getInsets();
|
|
Icon icon = getIcon(button);
|
|
int gap = button.getIconTextGap();
|
|
if (isLeftAligned(button, position)) {
|
|
return insets.left + icon.getIconWidth() + gap;
|
|
} else if (isRightAligned(button, position)) {
|
|
return insets.right + icon.getIconWidth() + gap;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
private Icon getIcon(AbstractButton button) {
|
|
Icon icon = button.getIcon();
|
|
if (icon != null) {
|
|
return icon;
|
|
}
|
|
String key = null;
|
|
if (button instanceof JCheckBox) {
|
|
key = "CheckBox.icon";
|
|
} else if (button instanceof JRadioButton) {
|
|
key = "RadioButton.icon";
|
|
}
|
|
if (key != null) {
|
|
Object oIcon = UIManager.get(key);
|
|
if (oIcon instanceof Icon) {
|
|
return (Icon)oIcon;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private boolean isLeftAligned(AbstractButton button, int position) {
|
|
if (position == SwingConstants.WEST) {
|
|
boolean ltr = button.getComponentOrientation().isLeftToRight();
|
|
int hAlign = button.getHorizontalAlignment();
|
|
return ((ltr && (hAlign == SwingConstants.LEFT ||
|
|
hAlign == SwingConstants.LEADING)) ||
|
|
(!ltr && (hAlign == SwingConstants.TRAILING)));
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private boolean isRightAligned(AbstractButton button, int position) {
|
|
if (position == SwingConstants.EAST) {
|
|
boolean ltr = button.getComponentOrientation().isLeftToRight();
|
|
int hAlign = button.getHorizontalAlignment();
|
|
return ((ltr && (hAlign == SwingConstants.RIGHT ||
|
|
hAlign == SwingConstants.TRAILING)) ||
|
|
(!ltr && (hAlign == SwingConstants.LEADING)));
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private int getInset(JComponent c, int position) {
|
|
return getInset(c.getInsets(), position);
|
|
}
|
|
|
|
private int getInset(Insets insets, int position) {
|
|
if (insets == null) {
|
|
return 0;
|
|
}
|
|
switch(position) {
|
|
case SwingConstants.NORTH:
|
|
return insets.top;
|
|
case SwingConstants.SOUTH:
|
|
return insets.bottom;
|
|
case SwingConstants.EAST:
|
|
return insets.right;
|
|
case SwingConstants.WEST:
|
|
return insets.left;
|
|
}
|
|
assert false;
|
|
return 0;
|
|
}
|
|
}
|