
com.jgoodies.forms.builder.AbstractI15dPanelBuilder Maven / Gradle / Ivy
Show all versions of jgoodiesforms Show documentation
/*
* Copyright (c) 2002-2012 JGoodies Karsten Lentzsch. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* o Neither the name of JGoodies Karsten Lentzsch nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jgoodies.forms.builder;
import java.awt.Component;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import com.jgoodies.common.swing.MnemonicUtils;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
/**
* An abstract panel builder class that uses the FormLayout
* to lay out JPanels. In addition to its superclass
* {@link PanelBuilder} this class provides convenience behavior to map
* resource keys to their associated internationalized (i15d) strings
* when adding labels, titles and titled separators.
*
* The localized texts used in methods {@code #addI15d*} can be
* marked texts, i.e. strings with an optional mnemonic marker.
* See the {@link MnemonicUtils} class comment for details.
*
* For debugging purposes you can automatically set a tooltip for the
* created labels that show its resource key. In case of an inproper
* resource localization, the label will show the wrong text, and the tooltip
* will help you identify the resource key with the broken localization.
* This feature can be enabled by calling {@code setDebugToolTipsEnabled}.
* If you want to enable it in a deployed application, you can set the system
* parameter {@code I15dPanelBuilder.debugToolTipsEnabled} to "true".
*
* Subclasses must implement the conversion from resource key
* to the localized string in {@code #getI15dString(String)}.
* For example class I15dPanelBuilder gets a ResourceBundle during
* construction, and requests strings from that bundle.
*
* @author Karsten Lentzsch
* @version $Revision: 1.12 $
*
* @since 1.1
*/
public abstract class AbstractI15dPanelBuilder extends PanelBuilder {
private static final String DEBUG_TOOL_TIPS_ENABLED_KEY =
"I15dPanelBuilder.debugToolTipsEnabled";
private static boolean debugToolTipsEnabled =
getDebugToolTipSystemProperty();
// Instance Creation ****************************************************
/**
* Constructs an AbstractI15dPanelBuilder for the given layout.
* Uses an instance of JPanel as layout container.
*
* @param layout the FormLayout used to lay out the container
*
* @throws NullPointerException if {@code layout} is {@code null}
*/
protected AbstractI15dPanelBuilder(FormLayout layout){
super(layout);
}
/**
* Constructs an AbstractI15dPanelBuilder
* for the given FormLayout and layout container.
*
* @param layout the FormLayout used to lay out the container
* @param container the layout container
*
* @throws NullPointerException if {@code layout} or {@code container} is {@code null}
*/
protected AbstractI15dPanelBuilder(FormLayout layout, JPanel container){
super(layout, container);
}
// Debug ToolTip Settings *************************************************
private static boolean getDebugToolTipSystemProperty() {
try {
String value = System.getProperty(DEBUG_TOOL_TIPS_ENABLED_KEY);
return "true".equalsIgnoreCase(value);
} catch (SecurityException e) {
return false;
}
}
/**
* Returns whether the debug tool tips are enabled or not.
*
* @return true if debug tool tips are enabled, false if disabled
*/
public static boolean isDebugToolTipsEnabled() {
return debugToolTipsEnabled;
}
/**
* Enables or disables the debug tool tips.
*
* @param b true to enable, false to disable
*/
public static void setDebugToolTipsEnabled(boolean b) {
debugToolTipsEnabled = b;
}
// Adding Labels and Separators *****************************************
/**
* Adds an internationalized (i15d) textual label to the form using the
* specified constraints.
*
* @param resourceKey the resource key for the label's text
* @param constraints the label's cell constraints
* @return the added label
*/
public final JLabel addI15dLabel(String resourceKey, CellConstraints constraints) {
JLabel label = addLabel(getI15dString(resourceKey), constraints);
if (isDebugToolTipsEnabled()) {
label.setToolTipText(resourceKey);
}
return label;
}
/**
* Adds an internationalized (i15d) textual label to the form using the
* specified constraints.
*
* @param resourceKey the resource key for the label's text
* @param encodedConstraints a string representation for the constraints
* @return the added label
*/
public final JLabel addI15dLabel(String resourceKey, String encodedConstraints) {
return addI15dLabel(resourceKey, new CellConstraints(encodedConstraints));
}
/**
* Adds an internationalized (i15d) label and component to the panel using
* the given cell constraints. Sets the label as the component label
* using {@link JLabel#setLabelFor(java.awt.Component)}.
*
* Note: The {@link CellConstraints} objects for the label
* and the component must be different. Cell constraints are implicitly
* cloned by the {@code FormLayout} when added to the container.
* However, in this case you may be tempted to reuse a
* {@code CellConstraints} object in the same way as with many other
* builder methods that require a single {@code CellConstraints}
* parameter.
* The pitfall is that the methods {@code CellConstraints.xy**(...)}
* just set the coordinates but do not create a new instance.
* And so the second invocation of {@code xy***(...)} overrides
* the settings performed in the first invocation before the object
* is cloned by the {@code FormLayout}.
*
* Wrong:
* builder.addI15dLabel("name.key",
* CC.xy(1, 7), // will be modified by the code below
* nameField,
* CC.xy(3, 7) // sets the single instance to (3, 7)
* );
*
* Correct:
* builder.addI15dLabel("name.key",
* CC.xy(1, 7).clone(), // cloned before the next modification
* nameField,
* CC.xy(3, 7) // sets this instance to (3, 7)
* );
*
*
* @param resourceKey the resource key for the label
* @param labelConstraints the label's cell constraints
* @param component the component to add
* @param componentConstraints the component's cell constraints
* @return the added label
* @throws IllegalArgumentException if the same cell constraints instance
* is used for the label and the component
* @see JLabel#setLabelFor(java.awt.Component)
*/
public final JLabel addI15dLabel(
String resourceKey, CellConstraints labelConstraints,
Component component, CellConstraints componentConstraints) {
JLabel label = addLabel(getI15dString(resourceKey), labelConstraints,
component, componentConstraints);
if (isDebugToolTipsEnabled()) {
label.setToolTipText(resourceKey);
}
return label;
}
// Adding Labels for Read-Only Fields *************************************
/**
* Adds an internationalized (i15d) textual label to the form using the
* specified constraints that is intended to label a read-only component.
*
* @param resourceKey the resource key for the label's text
* @param constraints the label's cell constraints
* @return the added label
*
* @since 1.3
*/
public final JLabel addI15dROLabel(String resourceKey, CellConstraints constraints) {
JLabel label = addROLabel(getI15dString(resourceKey), constraints);
if (isDebugToolTipsEnabled()) {
label.setToolTipText(resourceKey);
}
return label;
}
/**
* Adds an internationalized (i15d) textual label to the form using the
* specified constraints that is intended to label a read-only component.
*
* @param resourceKey the resource key for the label's text
* @param encodedConstraints a string representation for the constraints
* @return the added label
*
* @since 1.3
*/
public final JLabel addI15dROLabel(String resourceKey, String encodedConstraints) {
return addI15dROLabel(resourceKey, new CellConstraints(encodedConstraints));
}
/**
* Adds an internationalized (i15d) label and component to the panel using
* the given cell constraints. Intended for read-only components.
* Sets the label as the component label
* using {@link JLabel#setLabelFor(java.awt.Component)}.
*
* Note: The {@link CellConstraints} objects for the label
* and the component must be different. Cell constraints are implicitly
* cloned by the {@code FormLayout} when added to the container.
* However, in this case you may be tempted to reuse a
* {@code CellConstraints} object in the same way as with many other
* builder methods that require a single {@code CellConstraints}
* parameter.
* The pitfall is that the methods {@code CellConstraints.xy**(...)}
* just set the coordinates but do not create a new instance.
* And so the second invocation of {@code xy***(...)} overrides
* the settings performed in the first invocation before the object
* is cloned by the {@code FormLayout}.
*
* Wrong:
* builder.addI15dROLabel("name.key",
* CC.xy(1, 7), // will be modified by the code below
* nameField,
* CC.xy(3, 7) // sets the single instance to (3, 7)
* );
*
* Correct:
* builder.addI15dROLabel("name.key",
* CC.xy(1, 7).clone(), // cloned before the next modification
* nameField,
* CC.xy(3, 7) // sets this instance to (3, 7)
* );
*
* Better:
* builder.addI15dROLabel("name.key",
* CC.xy(1, 7) // creates a CellConstraints object
* nameField,
* CC.xy(3, 7) // creates another CellConstraints object
* );
*
*
* @param resourceKey the resource key for the label
* @param labelConstraints the label's cell constraints
* @param component the component to add
* @param componentConstraints the component's cell constraints
* @return the added label
*
* @throws IllegalArgumentException if the same cell constraints instance
* is used for the label and the component
*
* @see JLabel#setLabelFor(java.awt.Component)
*
* @since 1.3
*/
public final JLabel addI15dROLabel(
String resourceKey, CellConstraints labelConstraints,
Component component, CellConstraints componentConstraints) {
JLabel label = addROLabel(
getI15dString(resourceKey), labelConstraints,
component, componentConstraints);
if (isDebugToolTipsEnabled()) {
label.setToolTipText(resourceKey);
}
return label;
}
// Adding Titled Separators ***********************************************
/**
* Adds an internationalized (i15d) titled separator to the form using the
* specified constraints.
*
* @param resourceKey the resource key for the separator title
* @param constraints the separator's cell constraints
* @return the added titled separator
*/
public final JComponent addI15dSeparator(String resourceKey, CellConstraints constraints) {
JComponent component = addSeparator(getI15dString(resourceKey), constraints);
if (isDebugToolTipsEnabled()) {
component.setToolTipText(resourceKey);
}
return component;
}
/**
* Adds an internationalized (i15d) titled separator to the form using
* the specified constraints.
*
* @param resourceKey the resource key for the separator title
* @param encodedConstraints a string representation for the constraints
* @return the added titled separator
*/
public final JComponent addI15dSeparator(String resourceKey, String encodedConstraints) {
return addI15dSeparator(resourceKey, new CellConstraints(encodedConstraints));
}
/**
* Adds a title to the form using the specified constraints.
*
* @param resourceKey the resource key for the separator title
* @param constraints the separator's cell constraints
* @return the added title label
*/
public final JLabel addI15dTitle(String resourceKey, CellConstraints constraints) {
JLabel label = addTitle(getI15dString(resourceKey), constraints);
if (isDebugToolTipsEnabled()) {
label.setToolTipText(resourceKey);
}
return label;
}
/**
* Adds a title to the form using the specified constraints.
*
* @param resourceKey the resource key for the separator title
* @param encodedConstraints a string representation for the constraints
* @return the added title label
*/
public final JLabel addI15dTitle(String resourceKey, String encodedConstraints) {
return addI15dTitle(resourceKey, new CellConstraints(encodedConstraints));
}
// Abstract Behavior ******************************************************
/**
* Looks up and returns the internationalized (i15d) string for the given
* resource key, for example from a {@code ResourceBundle} or
* {@code ResourceMap}.
*
* @param resourceKey the key to look for in the resource map
* @return the associated internationalized string, or the resource key
* itself in case of a missing resource
* @throws IllegalStateException if the localization is not possible,
* for example, because no {@code ResourceBundle} has been set
*/
protected abstract String getI15dString(String resourceKey);
}