Path: blob/master/src/java.desktop/share/classes/sun/swing/DefaultLayoutStyle.java
41153 views
/*1* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/24package sun.swing;2526import java.awt.Container;27import java.awt.Insets;28import javax.swing.*;29import javax.swing.LayoutStyle.ComponentPlacement;30import javax.swing.border.Border;31import javax.swing.plaf.UIResource;3233/**34* An implementation of <code>LayoutStyle</code> that returns 6 for related35* components, otherwise 12. This class also provides helper methods for36* subclasses.37*38*/39public class DefaultLayoutStyle extends LayoutStyle {40private static final DefaultLayoutStyle INSTANCE =41new DefaultLayoutStyle();4243public static LayoutStyle getInstance() {44return INSTANCE;45}4647@Override48public int getPreferredGap(JComponent component1, JComponent component2,49ComponentPlacement type, int position, Container parent) {50if (component1 == null || component2 == null || type == null) {51throw new NullPointerException();52}5354checkPosition(position);5556if (type == ComponentPlacement.INDENT &&57(position == SwingConstants.EAST ||58position == SwingConstants.WEST)) {59int indent = getIndent(component1, position);60if (indent > 0) {61return indent;62}63}64return (type == ComponentPlacement.UNRELATED) ? 12 : 6;65}6667@Override68public int getContainerGap(JComponent component, int position,69Container parent) {70if (component == null) {71throw new NullPointerException();72}73checkPosition(position);74return 6;75}7677/**78* Returns true if the classes identify a JLabel and a non-JLabel79* along the horizontal axis.80*/81protected boolean isLabelAndNonlabel(JComponent c1, JComponent c2,82int position) {83if (position == SwingConstants.EAST ||84position == SwingConstants.WEST) {85boolean c1Label = (c1 instanceof JLabel);86boolean c2Label = (c2 instanceof JLabel);87return ((c1Label || c2Label) && (c1Label != c2Label));88}89return false;90}9192/**93* For some look and feels check boxs and radio buttons typically94* don't paint the border, yet they have padding for a border. Look95* and feel guidelines generally don't include this space. Use96* this method to subtract this space from the specified97* components.98*99* @param source First component100* @param target Second component101* @param position Position doing layout along.102* @param offset Ideal offset, not including border/margin103* @return offset - border/margin around the component.104*/105protected int getButtonGap(JComponent source, JComponent target,106int position, int offset) {107offset -= getButtonGap(source, position);108if (offset > 0) {109offset -= getButtonGap(target, flipDirection(position));110}111if (offset < 0) {112return 0;113}114return offset;115}116117/**118* For some look and feels check boxs and radio buttons typically119* don't paint the border, yet they have padding for a border. Look120* and feel guidelines generally don't include this space. Use121* this method to subtract this space from the specified122* components.123*124* @param source Component125* @param position Position doing layout along.126* @param offset Ideal offset, not including border/margin127* @return offset - border/margin around the component.128*/129protected int getButtonGap(JComponent source, int position, int offset) {130offset -= getButtonGap(source, position);131return Math.max(offset, 0);132}133134/**135* If <code>c</code> is a check box or radio button, and the border is136* not painted this returns the inset along the specified axis.137*/138public int getButtonGap(JComponent c, int position) {139String classID = c.getUIClassID();140if ((classID == "CheckBoxUI" || classID == "RadioButtonUI") &&141!((AbstractButton)c).isBorderPainted()) {142Border border = c.getBorder();143if (border instanceof UIResource) {144return getInset(c, position);145}146}147return 0;148}149150private void checkPosition(int position) {151if (position != SwingConstants.NORTH &&152position != SwingConstants.SOUTH &&153position != SwingConstants.WEST &&154position != SwingConstants.EAST) {155throw new IllegalArgumentException();156}157}158159protected int flipDirection(int position) {160switch(position) {161case SwingConstants.NORTH:162return SwingConstants.SOUTH;163case SwingConstants.SOUTH:164return SwingConstants.NORTH;165case SwingConstants.EAST:166return SwingConstants.WEST;167case SwingConstants.WEST:168return SwingConstants.EAST;169}170assert false;171return 0;172}173174/**175* Returns the amount to indent the specified component if it's176* a JCheckBox or JRadioButton. If the component is not a JCheckBox or177* JRadioButton, 0 will be returned.178*/179protected int getIndent(JComponent c, int position) {180String classID = c.getUIClassID();181if (classID == "CheckBoxUI" || classID == "RadioButtonUI") {182AbstractButton button = (AbstractButton)c;183Insets insets = c.getInsets();184Icon icon = getIcon(button);185int gap = button.getIconTextGap();186if (isLeftAligned(button, position)) {187return insets.left + icon.getIconWidth() + gap;188} else if (isRightAligned(button, position)) {189return insets.right + icon.getIconWidth() + gap;190}191}192return 0;193}194195private Icon getIcon(AbstractButton button) {196Icon icon = button.getIcon();197if (icon != null) {198return icon;199}200String key = null;201if (button instanceof JCheckBox) {202key = "CheckBox.icon";203} else if (button instanceof JRadioButton) {204key = "RadioButton.icon";205}206if (key != null) {207Object oIcon = UIManager.get(key);208if (oIcon instanceof Icon) {209return (Icon)oIcon;210}211}212return null;213}214215private boolean isLeftAligned(AbstractButton button, int position) {216if (position == SwingConstants.WEST) {217boolean ltr = button.getComponentOrientation().isLeftToRight();218int hAlign = button.getHorizontalAlignment();219return ((ltr && (hAlign == SwingConstants.LEFT ||220hAlign == SwingConstants.LEADING)) ||221(!ltr && (hAlign == SwingConstants.TRAILING)));222}223return false;224}225226private boolean isRightAligned(AbstractButton button, int position) {227if (position == SwingConstants.EAST) {228boolean ltr = button.getComponentOrientation().isLeftToRight();229int hAlign = button.getHorizontalAlignment();230return ((ltr && (hAlign == SwingConstants.RIGHT ||231hAlign == SwingConstants.TRAILING)) ||232(!ltr && (hAlign == SwingConstants.LEADING)));233}234return false;235}236237private int getInset(JComponent c, int position) {238return getInset(c.getInsets(), position);239}240241private int getInset(Insets insets, int position) {242if (insets == null) {243return 0;244}245switch(position) {246case SwingConstants.NORTH:247return insets.top;248case SwingConstants.SOUTH:249return insets.bottom;250case SwingConstants.EAST:251return insets.right;252case SwingConstants.WEST:253return insets.left;254}255assert false;256return 0;257}258}259260261