ch.randelshofer.quaqua.QuaquaLayoutStyle15 Maven / Gradle / Ivy
Show all versions of Quaqua Show documentation
/*
* @(#)QuaquaLayoutStyle15.java
*
* Copyright (c) 2005-2010 Werner Randelshofer, Immensee, Switzerland.
* All rights reserved.
*
* You may not use, copy or modify this file, except in compliance with the
* license agreement you entered into with Werner Randelshofer.
* For details see accompanying license terms.
*/
package ch.randelshofer.quaqua;
import java.awt.*;
import javax.swing.*;
import java.lang.reflect.*;
import java.util.*;
/**
* A QuaquaLayoutStyle15 can be queried for the preferred gaps between two
* JComponents, or between a JComponent and a parent Container.
*
* To compile this class, you need the experimental SwingLayout package.
*
* This class is here for backwards compatibilty with J2SE5.
*
* @author Werner Randelshofer
* @version $Id: QuaquaLayoutStyle15.java 361 2010-11-21 11:19:20Z wrandelshofer $
*/
public class QuaquaLayoutStyle15 extends org.jdesktop.layout.LayoutStyle {
private final static boolean DEBUG = false;
/** Mini size style. */
private final static int MINI = 0;
/** Small size style. */
private final static int SMALL = 1;
/** Regular size style. */
private final static int REGULAR = 2;
/**
* The containerGapDefinitions array defines the preferred insets (child gaps)
* of a parent container towards one of its child components.
*
* Note: As of now, we do not yet specify the preferred gap from a child
* to its parent. Therefore we may not be able to treat all special cases.
*
* This array is used to initialize the containerGaps HashMap.
*
* The array has the following structure, which is supposed to be a
* a compromise between legibility and code size.
* containerGapDefinitions[0..n] = preferred insets for some parent UI's
* containerGapDefinitions[][0..m-3] = name of parent UI,
* optionally followed by a full stop and
* a style name
* containerGapDefinitions[][m-2] = mini insets
* containerGapDefinitions[][m-1] = small insets
* containerGapDefinitions[][m] = regular insets
*/
private final static Object[][] containerGapDefinitions = {
// Format:
// { list of parent UI's,
// mini insets, small insets, regular insets }
{ "TabbedPaneUI",
new Insets(6,10,10,10), new Insets(6,10,10,12), new Insets(12,20,20,20)
},
// http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGLayout/chapter_19_section_3.html#//apple_ref/doc/uid/TP30000360/DontLinkElementID_27
// http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGLayout/chapter_19_section_3.html#//apple_ref/doc/uid/TP30000360/DontLinkElementID_26
// note for small and mini size: leave 8 to 10 pixels on top
// note for regular size: leave only 12 pixel at top if tabbed pane UI
{ "RootPaneUI",
new Insets(8,10,10,10), new Insets(8,10,10,12), new Insets(14,20,20,20)
},
// These child gaps are used for all other components
{ "default",
new Insets(8,10,10,10), new Insets(8,10,10,12), new Insets(14,20,20,20)
},
};
/**
* The relatedGapDefinitions table defines the preferred gaps
* of one party of two related components.
*
* The effective preferred gap is the maximum of the preferred gaps of
* both parties.
*
* This array is used to initialize the relatedGaps HashMap.
*
* The array has the following structure, which is supposed to be a
* a compromise between legibility and code size.
* containerGapDefinitions[0..n] = preferred gaps for a party of a two related UI's
* containerGapDefinitions[][0..m-3] = name of UI
* optionally followed by a full stop and
* a style name
* containerGapDefinitions[][m-2] = mini insets
* containerGapDefinitions[][m-1] = small insets
* containerGapDefinitions[][m] = regular insets
*/
private final static Object[][] relatedGapDefinitions = {
// Format:
// { list of UI's,
// mini insets, small insets, regular insets }
// Push Button:
// http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGControls/chapter_18_section_2.html#//apple_ref/doc/uid/20000957-TP30000359-TPXREF104
{ "ButtonUI", "ButtonUI.push", "ButtonUI.text",
"ToggleButtonUI.push", "ToggleButtonUI.text",
new Insets(8,8,8,8), new Insets(10,10,10,10), new Insets(12,12,12,12)
},
// Metal Button
// http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGControls/chapter_18_section_2.html#//apple_ref/doc/uid/20000957-TP30000359-TPXREF187
{ "ButtonUI.metal", "ToggleButtonUI.metal",
new Insets(8,8,8,8), new Insets(8,8,8,8), new Insets(12,12,12,12)
},
// Bevel Button (Rounded and Square)
// http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGControls/chapter_18_section_2.html#//apple_ref/doc/uid/20000957-TP30000359-TPXREF112
{ "ButtonUI.bevel", "ButtonUI.toggle", "ButtonUI.square",
"ToggleButtonUI", "ToggleButtonUI.bevel", "ToggleButtonUI.square", "ToggleButtonUI.toggle",
new Insets(0,0,0,0), new Insets(0,0,0,0), new Insets(0,0,0,0)
},
// Bevel Button (Rounded and Square)
// http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGControls/chapter_18_section_2.html#//apple_ref/doc/uid/20000957-TP30000359-TPXREF112
{ "ButtonUI.bevel.largeIcon", "ToggleButtonUI.bevel.largeIcon",
new Insets(8,8,8,8), new Insets(8,8,8,8), new Insets(8,8,8,8)
},
// Icon Button
// http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGControls/chapter_18_section_2.html#//apple_ref/doc/uid/20000957-TP30000359-TPXREF189
{ "ButtonUI.icon",
new Insets(0,0,0,0), new Insets(0,0,0,0), new Insets(0,0,0,0)
},
{ "ButtonUI.icon.largeIcon",
new Insets(8,8,8,8), new Insets(8,8,8,8), new Insets(8,8,8,8)
},
// Round Button
// http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGControls/chapter_18_section_2.html#//apple_ref/doc/uid/20000957-TP30000359-TPXREF191
{ "ButtonUI.round", "ToggleButtonUI.round",
new Insets(12,12,12,12), new Insets(12,12,12,12), new Insets(12,12,12,12)
},
// Help Button
// http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGControls/chapter_18_section_2.html#//apple_ref/doc/uid/20000957-TP30000359-TPXREF193
{ "ButtonUI.help",
new Insets(12,12,12,12), new Insets(12,12,12,12), new Insets(12,12,12,12)
},
// Segmented Control
// http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGControls/chapter_18_section_3.html#//apple_ref/doc/uid/20000957-TP30000359-TPXREF196
{ "ButtonUI.toggleCenter", "ToggleButtonUI.toggleCenter",
new Insets(8,0,8,0), new Insets(10,0,10,0), new Insets(12,0,12,0)
},
{ "ButtonUI.toggleEast", "ToggleButtonUI.toggleEast",
new Insets(8,0,8,8), new Insets(10,0,10,10), new Insets(12,0,12,12)
},
{ "ButtonUI.toggleWest", "ToggleButtonUI.toggleWest",
new Insets(8,8,8,0), new Insets(10,10,10,0), new Insets(12,12,12,0)
},
{ "ButtonUI.toolBarTab", "ToggleButtonUI.toolBarTab",
new Insets(0,0,0,0), new Insets(0,0,0,0), new Insets(0,0,0,0)
},
// Color Well Button
// http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGControls/chapter_18_section_3.html#//apple_ref/doc/uid/20000957-TP30000359-TPXREF213
{ "ButtonUI.colorWell", "ToggleButtonUI.colorWell",
new Insets(0,0,0,0), new Insets(0,0,0,0), new Insets(0,0,0,0)
},
// http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGControls/chapter_18_section_3.html#//apple_ref/doc/uid/20000957-TP30000359-TPXREF198
// FIXME - The following values are given in the AHIG.
// In reality, the values further below seem to be more appropriate.
// Which ones are right?
//{ "CheckBoxUI", new Insets(7, 5, 7, 5), new Insets(8, 6, 8, 6), new Insets(8, 8, 8, 8) },
{ "CheckBoxUI",
new Insets(6, 5, 6, 5), new Insets(7, 6, 7, 6), new Insets(7, 6, 7, 6)
},
// http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGControls/chapter_18_section_3.html#//apple_ref/doc/uid/20000957-TP30000359-TPXREF198
{ "ComboBoxUI",
new Insets(8, 5, 8, 5), new Insets(10, 6, 10, 6), new Insets(12, 8, 12, 8)
},
// There is no spacing given for labels in Apples Guidelines.
// We use the values here, which is the minimum of the spacing of all
// other components.
{ "LabelUI",
new Insets(6, 8, 6, 8), new Insets(6, 8, 6, 8), new Insets(6, 8, 6, 8)
},
// ? spacing not given
{ "ListUI",
new Insets(5, 5, 5, 5), new Insets(6, 6, 6, 6), new Insets(6, 6, 6, 6)
},
// ? spacing not given
{ "PanelUI",
new Insets(0, 0, 0, 0), new Insets(0, 0, 0, 0), new Insets(0, 0, 0, 0)
},
// http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGControls/chapter_18_section_5.html#//apple_ref/doc/uid/20000957-TP30000359-TPXREF106
// ? spacing not given
{ "ProgressBarUI",
new Insets(8,8,8,8), new Insets(10,10,10,10), new Insets(12,12,12,12)
},
// http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGControls/chapter_18_section_3.html#//apple_ref/doc/uid/20000957-TP30000359-BIAHBFAD
{ "RadioButtonUI",
new Insets(5, 5, 5, 5), new Insets(6, 6, 6, 6), new Insets(6, 6, 6, 6)
},
//http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGControls/chapter_18_section_6.html#//apple_ref/doc/uid/20000957-TP30000359-TPXREF114
// ? spacing not given. We use the same like for text fields
{ "ScrollPaneUI",
new Insets(6, 8, 6, 8), new Insets(6, 8, 6, 8), new Insets(8, 10, 8, 10)
},
//http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGControls/chapter_18_section_8.html#//apple_ref/doc/uid/20000957-TP30000359-TPXREF214
// ? spacing not given
//http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGLayout/chapter_19_section_2.html#//apple_ref/doc/uid/20000957-TP30000360-CHDEACGD
{ "SeparatorUI",
new Insets(8, 8, 8, 8), new Insets(10, 10, 10, 10), new Insets(12, 12, 12, 12)
},
// http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGControls/chapter_18_section_4.html#//apple_ref/doc/uid/20000957-TP30000359-TPXREF115
{ "SliderUI.horizontal",
new Insets(6,8,6,8), new Insets(6,10,6,10), new Insets(6,12,6,12)
},
{ "SliderUI.vertical",
new Insets(8,8,8,8), new Insets(10,10,10,10), new Insets(12,12,12,12)
},
//http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGControls/chapter_18_section_4.html#//apple_ref/doc/uid/20000957-TP30000359-TPXREF204
{ "SpinnerUI",
new Insets(6, 8, 6, 8), new Insets(6, 8, 6, 8), new Insets(8, 10, 8, 10)
},
// http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGControls/chapter_18_section_7.html#//apple_ref/doc/uid/20000957-TP30000359-CHDDBIJE
// ? spacing not given
{ "SplitPaneUI",
new Insets(0,0,0,0), new Insets(0,0,0,0), new Insets(0,0,0,0)
},
// http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGControls/chapter_18_section_7.html#//apple_ref/doc/uid/20000957-TP30000359-TPXREF105
// ? spacing not given
{ "TabbedPaneUI",
new Insets(0,0,0,0), new Insets(0,0,0,0), new Insets(0,0,0,0)
},
{ "TableUI",
new Insets(0,0,0,0), new Insets(0,0,0,0), new Insets(0,0,0,0)
},
// ? spacing not given
{ "TextAreaUI", "EditorPaneUI", "TextPaneUI",
new Insets(0,0,0,0), new Insets(0,0,0,0), new Insets(0,0,0,0)
},
//http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/XHIGControls/chapter_18_section_6.html#//apple_ref/doc/uid/20000957-TP30000359-TPXREF225
{ "TextFieldUI", "FormattedTextFieldUI", "PasswordFieldUI",
new Insets(6, 8, 6, 8), new Insets(6, 8, 6, 8), new Insets(8, 10, 8, 10)
},
// ? spacing not given
{ "TreeUI",
new Insets(0,0,0,0), new Insets(0,0,0,0), new Insets(0,0,0,0)
},
};
private final static Object[][] unrelatedGapDefinitions = {
// UI, mini, small, regular
{ "ButtonUI.help",
new Insets(24,24,24,24), new Insets(24,24,24,24), new Insets(24,24,24,24)
},
{ "default",
new Insets(12, 12, 12, 12), new Insets(14, 14, 14, 14), new Insets(16, 16, 16, 16)
},
};
/**
* The indentGapDefinitions table defines the preferred indentation
* for components that are indented after the specified component.
*
* This array is used to initialize the indentGaps HashMap.
*
* The array has the following structure, which is supposed to be a
* a compromise between legibility and code size.
* indentGapDefinitions[0..n] = preferred gaps for a party of a two related UI's
* indentGapDefinitions[][0..m-3] = name of UI
* optionally followed by a full stop and
* a style name
* indentGapDefinitions[][m-2] = mini insets
* indentGapDefinitions[][m-1] = small insets
* indentGapDefinitions[][m] = regular insets
*/
private final static Object[][] indentGapDefinitions = {
// UI, mini, small, regular
{ "default",
new Insets(16, 16, 16, 16), new Insets(20, 20, 20, 20), new Insets(25, 25, 25, 25)
},
};
/**
* Creates a hash map for the specified definitions array.
*
* Each entry of the hash map has the name of an UI (optionally followed by
* a full stop and a style name) as its key
* and an array of Insets as its value .
*/
private static HashMap createMap(Object[][] definitions) {
HashMap map = new HashMap();
for (int i=0; i < definitions.length; i++) {
int keys = 0;
while (keys < definitions[i].length
&& (definitions[i][keys] instanceof String)) {
keys++;
}
Insets[] values = new Insets[definitions[i].length - keys];
for (int j=keys; j < definitions[i].length; j++) {
values[j-keys] = (Insets) definitions[i][j];
}
for (int j=0; j < keys; j++) {
map.put(definitions[i][j], values);
}
}
return map;
}
/**
* The relatedGapDefinitions table defines the preferred gaps
* of one party of two related components.
*/
private final static HashMap relatedGaps = createMap(relatedGapDefinitions);
/**
* The unrelatedGapDefinitions table defines the preferred gaps
* of one party of two unrelated components.
*/
private final static HashMap unrelatedGaps = createMap(unrelatedGapDefinitions);
/**
* The containerGapDefinitions array defines the preferred insets (child gaps)
* of a parent component towards one of its children.
*/
private final static HashMap containerGaps = createMap(containerGapDefinitions);
/**
* The indentGapDefinitions table defines the preferred indentation
* for components that are indented after the specified component.
*/
private final static HashMap indentGaps = createMap(indentGapDefinitions);
/**
* Creates a new instance.
*/
public QuaquaLayoutStyle15() {
}
/**
* Returns the amount of space to use between two components.
* The return value indicates the distance to place
* component2
relative to component1
.
* For example, the following returns the amount of space to place
* between component2
and component1
* when component2
is placed vertically above
* component1
:
*
* int gap = getPreferredGap(component1, component2,
* LayoutStyle.RELATED,
* SwingConstants.NORTH, parent);
*
* The type
parameter indicates the type
* of gap being requested. It can be one of the following values:
*
* RELATED
* If the two components will be contained in
* the same parent and are showing similar logically related
* items, use RELATED
.
* UNRELATED
* If the two components will be
* contained in the same parent but show logically unrelated items
* use UNRELATED
.
* INDENT
* Used to obtain the preferred distance to indent a component
* relative to another. For example, if you want to horizontally
* indent a JCheckBox relative to a JLabel use INDENT
.
* This is only useful for the horizontal axis.
*
*
* It's important to note that some look and feels may not distinguish
* between RELATED
and UNRELATED
.
*
* The return value is not intended to take into account the
* current size and position of component2
or
* component1
. The return value may take into
* consideration various properties of the components. For
* example, the space may vary based on font size, or the preferred
* size of the component.
*
* @param component1 the JComponent
* component2
is being placed relative to
* @param component2 the JComponent
being placed
* @param type how the two components are being placed
* @param position the position component2
is being placed
* relative to component1
; one of
* SwingConstants.NORTH
,
* SwingConstants.SOUTH
,
* SwingConstants.EAST
or
* SwingConstants.WEST
* @param parent the parent of component2
; this may differ
* from the actual parent and may be null
* @return the amount of space to place between the two components
* @throws IllegalArgumentException if position
is not
* one of SwingConstants.NORTH
,
* SwingConstants.SOUTH
,
* SwingConstants.EAST
or
* SwingConstants.WEST
; type
not one
* of INDENT
, RELATED
* or UNRELATED
; or component1
or
* component2
is null
*/
@Override
public int getPreferredGap(JComponent component1, JComponent component2,
int type, int position, Container parent) {
int result;
if (type == INDENT) {
// Compute gap
int sizeVariant = getSizeVariant(component1);
Insets vgap = getVisualIndent(component1);
Insets pgap = getPreferredGap(component1, INDENT, sizeVariant);
switch (position) {
case SwingConstants.NORTH :
result = (vgap.bottom > 8) ? vgap.bottom : pgap.bottom;
break;
case SwingConstants.SOUTH :
result = (vgap.top > 8) ? vgap.top : pgap.top;
break;
case SwingConstants.EAST :
result = (vgap.left > 8) ? vgap.left : pgap.left;
break;
case SwingConstants.WEST :
default :
result = (vgap.right > 8) ? vgap.right : pgap.right;
break;
}
// Compensate for visual margin
Insets visualMargin2 = getVisualMargin(component2);
switch (position) {
case SwingConstants.NORTH :
result -= visualMargin2.bottom;
break;
case SwingConstants.SOUTH :
result -= visualMargin2.top;
break;
case SwingConstants.EAST :
result -= visualMargin2.left;
break;
case SwingConstants.WEST :
result -= visualMargin2.right;
default :
break;
}
} else {
// If the two components have different size styles, we use the
// smaller size style to determine the gap
int sizeVariant = Math.min(getSizeVariant(component1), getSizeVariant(component2));
Insets gap1 = getPreferredGap(component1, type, sizeVariant);
Insets gap2 = getPreferredGap(component2, type, sizeVariant);
// The AHIG defines the minimal spacing for a component
// therefore we use the larger of the two gap values.
switch (position) {
case SwingConstants.NORTH :
result = Math.max(gap1.top, gap2.bottom);
break;
case SwingConstants.SOUTH :
result = Math.max(gap1.bottom, gap2.top);
break;
case SwingConstants.EAST :
result = Math.max(gap1.right, gap2.left);
break;
case SwingConstants.WEST :
default :
result = Math.max(gap1.left, gap2.right);
break;
}
// Compensate for visual margin
Insets visualMargin1 = getVisualMargin(component1);
Insets visualMargin2 = getVisualMargin(component2);
switch (position) {
case SwingConstants.NORTH :
result -= visualMargin1.top + visualMargin2.bottom;
break;
case SwingConstants.SOUTH :
result -= visualMargin1.bottom + visualMargin2.top;
break;
case SwingConstants.EAST :
result -= visualMargin1.right + visualMargin2.left;
break;
case SwingConstants.WEST :
result -= visualMargin1.left + visualMargin2.right;
default :
break;
}
}
return result;
}
private Insets getPreferredGap(JComponent component, int type, int sizeStyle) {
Insets gap = null;
HashMap gapMap;
switch (type) {
case INDENT :
gapMap = indentGaps; break;
case RELATED :
gapMap = relatedGaps; break;
case UNRELATED :
default :
gapMap = unrelatedGaps; break;
}
String uid = component.getUIClassID();
String style = null;
if (uid.equals("ButtonUI") || uid.equals("ToggleButtonUI")) {
style = (String) component.getClientProperty("Quaqua.Button.style");
if (style == null) {
style = (String) component.getClientProperty("JButton.buttonType");
}
} else if (uid.equals("ProgressBarUI")) {
style = (((JProgressBar) component).getOrientation() == JProgressBar.HORIZONTAL)
? "horizontal"
: "vertical";
} else if (uid.equals("SliderUI")) {
style = (((JSlider) component).getOrientation() == JSlider.HORIZONTAL)
? "horizontal"
: "vertical";
} else if (uid.equals("TabbedPaneUI")) {
switch (((JTabbedPane) component).getTabPlacement()) {
case JTabbedPane.TOP : style = "top"; break;
case JTabbedPane.LEFT : style = "left"; break;
case JTabbedPane.BOTTOM : style = "bottom"; break;
case JTabbedPane.RIGHT : style = "right"; break;
}
}
String key = (style == null) ? uid : uid+"."+style;
Insets[] gaps = (Insets[]) gapMap.get(key);
if (gaps == null) {
gaps = (Insets[]) gapMap.get(uid);
}
if (gaps == null) {
gaps = (Insets[]) gapMap.get("default");
}
return (gaps == null) ? new Insets(0,0,0,0) : (Insets) gaps[sizeStyle].clone();
}
/**
* Returns the amount of space to position a component inside its
* parent.
*
* @param component the Component
being positioned
* @param position the position component
is being placed
* relative to its parent; one of
* SwingConstants.NORTH
,
* SwingConstants.SOUTH
,
* SwingConstants.EAST
or
* SwingConstants.WEST
* @param parent the parent of component
; this may differ
* from the actual parent and may be null
* @return the amount of space to place between the component and specified
* edge
* @throws IllegalArgumentException if position
is not
* one of SwingConstants.NORTH
,
* SwingConstants.SOUTH
,
* SwingConstants.EAST
or
* SwingConstants.WEST
;
* or component
is null
*/
@Override
public int getContainerGap(JComponent component, int position,
Container parent) {
int result;
int sizeVariant = Math.min(getSizeVariant(component), getSizeVariant(parent));
// Compute gap
Insets gap = getContainerGap(parent, sizeVariant);
switch (position) {
case SwingConstants.NORTH :
result = gap.top;
break;
case SwingConstants.SOUTH :
result = gap.bottom;
break;
case SwingConstants.EAST :
result = gap.right;
break;
case SwingConstants.WEST :
default :
result = gap.left;
break;
}
// Compensate for visual margin
Insets visualMargin = getVisualMargin(component);
switch (position) {
case SwingConstants.NORTH :
result -= visualMargin.top;
break;
case SwingConstants.SOUTH :
result -= visualMargin.bottom;
// Radio buttons in Quaqua are 1 pixel too high, in order
// to align their baselines with other components, when no
// baseline aware layout manager is used.
if (component instanceof JRadioButton) {
result--;
}
break;
case SwingConstants.EAST :
result -= visualMargin.left;
break;
case SwingConstants.WEST :
result -= visualMargin.right;
default :
break;
}
return result;
}
private Insets getContainerGap(Container container, int sizeStyle) {
Insets gap = null;
HashMap gapMap = containerGaps;
String uid;
if (container instanceof JComponent) {
uid = ((JComponent) container).getUIClassID();
} else if (container instanceof Dialog) {
uid = "Dialog";
} else if (container instanceof Frame) {
uid = "Frame";
} else if (container instanceof java.applet.Applet) {
uid = "Applet";
} else if (container instanceof Panel) {
uid = "Panel";
} else {
uid = "default";
}
String style = null;
// FIXME insert style code here for JInternalFrame with palette style
String key = (style == null) ? uid : uid+"."+style;
Insets[] gaps = (Insets[]) gapMap.get(key);
if (gaps == null) {
gaps = (Insets[]) gapMap.get(uid);
}
if (gaps == null) {
gaps = (Insets[]) gapMap.get("default");
}
if (gaps == null) {
if (DEBUG) System.out.println("AquaLayoutStyle.noGaps for "+uid);
}
return (gaps == null) ? new Insets(0,0,0,0) : (Insets) gaps[sizeStyle].clone();
}
private Insets getVisualMargin(JComponent component) {
try {
Method getUI = component.getClass().getMethod("getUI", new Class[0]);
Object ui = getUI.invoke(component, new Object[0]);
if (ui instanceof VisuallyLayoutable) {
Dimension size = component.getPreferredSize();
Rectangle visualBounds = ((VisuallyLayoutable) ui).getVisualBounds(component, VisuallyLayoutable.COMPONENT_BOUNDS, size.width, size.height);
return new Insets(visualBounds.y, visualBounds.x, size.height - visualBounds.y - visualBounds.height, size.width - visualBounds.x - visualBounds.width);
}
} catch (NoSuchMethodException e) {
// This can happen for subclasses of JComponent, which do
// not have an UI delegate.
// Fall through.
} catch (Exception e) {
InternalError error = new InternalError();
error.initCause(e);
throw error;
}
return new Insets(0,0,0,0);
}
private Insets getVisualIndent(JComponent component) {
try {
Method getUI = component.getClass().getMethod("getUI", new Class[0]);
Object ui = getUI.invoke(component, new Object[0]);
if (ui instanceof VisuallyLayoutable) {
Dimension size = component.getPreferredSize();
Rectangle visualBounds = ((VisuallyLayoutable) ui).getVisualBounds(component, VisuallyLayoutable.TEXT_BOUNDS, size.width, size.height);
return new Insets(visualBounds.y, visualBounds.x, size.height - visualBounds.y - visualBounds.height, size.width - visualBounds.x - visualBounds.width);
}
} catch (NoSuchMethodException e) {
// This can happen for subclasses of JComponent, which do
// not have an UI delegate.
// Fall through
} catch (Exception e) {
InternalError error = new InternalError();
error.initCause(e);
throw error;
}
return new Insets(0,0,0,0);
}
/**
* Returns the size variant of a specified component.
*
* @return REGULAR, SMALL or MINI.
*/
private int getSizeVariant(Component c) {
// Look for size variant client property
if (c instanceof JComponent) {
String variant = (String) ((JComponent) c).getClientProperty("JComponent.sizeVariant");
if (variant != null) {
if (variant.equals("regular")) {
return REGULAR;
}
if (variant.equals("mini")) {
return MINI;
}
if (variant.equals("small")) {
return SMALL;
}
}
}
// Aqua components have a different style depending on the
// font size used.
// 13 Point = Regular
// 11 Point = Small
// 9 Point = Mini
Font f = c.getFont();
if (f==null) return REGULAR;
int fontSize = f.getSize();
return (fontSize >= 13) ? REGULAR : ((fontSize > 9) ? SMALL : MINI);
}
}