001/* 002 * Copyright (c) 2002-2006 JGoodies Karsten Lentzsch. All Rights Reserved. 003 * 004 * Redistribution and use in source and binary forms, with or without 005 * modification, are permitted provided that the following conditions are met: 006 * 007 * o Redistributions of source code must retain the above copyright notice, 008 * this list of conditions and the following disclaimer. 009 * 010 * o Redistributions in binary form must reproduce the above copyright notice, 011 * this list of conditions and the following disclaimer in the documentation 012 * and/or other materials provided with the distribution. 013 * 014 * o Neither the name of JGoodies Karsten Lentzsch nor the names of 015 * its contributors may be used to endorse or promote products derived 016 * from this software without specific prior written permission. 017 * 018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 020 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 021 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 022 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 023 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 024 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 025 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 026 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 027 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 028 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030 031package com.jgoodies.forms.builder; 032 033import java.awt.Component; 034import java.util.MissingResourceException; 035import java.util.ResourceBundle; 036 037import javax.swing.JComponent; 038import javax.swing.JLabel; 039import javax.swing.JPanel; 040 041import com.jgoodies.forms.layout.CellConstraints; 042import com.jgoodies.forms.layout.FormLayout; 043 044/** 045 * A general purpose panel builder that uses the {@link FormLayout} 046 * to lay out <code>JPanel</code>s. In addition to its superclass 047 * {@link PanelBuilder} this class provides convenience behavior to map 048 * resource keys to their associated internationalized (i15d) strings 049 * when adding labels, titles and titled separators.<p> 050 * 051 * The localized texts used in methods <code>#addI15dLabel</code> 052 * and <code>#addI15dTitle</code> can contain an optional mnemonic marker. 053 * The mnemonic and mnemonic index are indicated by a single ampersand 054 * (<tt>&</tt>). For example <tt>"&Save"</tt>, or 055 * <tt>"Save &as"</tt>. To use the ampersand itself, 056 * duplicate it, for example <tt>"Look&&Feel"</tt>.<p> 057 * 058 * @author Karsten Lentzsch 059 * @version $Revision$ 060 * @since 1.0.3 061 * 062 * @see ResourceBundle 063 */ 064public class I15dPanelBuilder extends PanelBuilder { 065 066 /** 067 * Holds the <code>ResourceBundle</code> used to lookup internationalized 068 * (i15d) String resources. 069 */ 070 private final ResourceBundle bundle; 071 072 // Instance Creation **************************************************** 073 074 /** 075 * Constructs an instance of <code>I15dPanelBuilder</code> for the given 076 * layout. Uses an instance of <code>JPanel</code> as layout container. 077 * 078 * @param layout the form layout used to layout the container 079 * @param bundle the resource bundle used to lookup i15d strings 080 */ 081 public I15dPanelBuilder(FormLayout layout, ResourceBundle bundle) { 082 this(new JPanel(null), layout, bundle); 083 } 084 085 /** 086 * Constructs an instance of <code>I15dPanelBuilder</code> 087 * for the given FormLayout and layout container. 088 * 089 * @param layout the <code>FormLayout</code> used to layout the container 090 * @param bundle the <code>ResourceBundle</code> used to lookup i15d strings 091 * @param panel the layout container 092 */ 093 public I15dPanelBuilder(FormLayout layout, ResourceBundle bundle, 094 JPanel panel) { 095 super(layout, panel); 096 this.bundle = bundle; 097 } 098 099 /** 100 * Constructs an instance of <code>I15dPanelBuilder</code> 101 * for the given FormLayout and layout container. 102 * 103 * @param panel the layout container 104 * @param bundle the <code>ResourceBundle</code> used to lookup i15d strings 105 * @param layout the <code>FormLayout</code> used to layout the container 106 * 107 * @deprecated Replaced by {@link #I15dPanelBuilder(FormLayout, ResourceBundle, JPanel)}. 108 */ 109 @Deprecated 110 public I15dPanelBuilder(JPanel panel, FormLayout layout, 111 ResourceBundle bundle) { 112 this(layout, bundle, panel); 113 } 114 115 // Adding Labels and Separators ***************************************** 116 117 /** 118 * Adds an internationalized (i15d) textual label to the form using the 119 * specified constraints. 120 * 121 * @param resourceKey the resource key for the label's text 122 * @param constraints the label's cell constraints 123 * @return the added label 124 */ 125 public final JLabel addI15dLabel(String resourceKey, 126 CellConstraints constraints) { 127 return addLabel(getI15dString(resourceKey), constraints); 128 } 129 130 /** 131 * Adds an internationalized (i15d) textual label to the form using the 132 * specified constraints. 133 * 134 * @param resourceKey the resource key for the label's text 135 * @param encodedConstraints a string representation for the constraints 136 * @return the added label 137 */ 138 public final JLabel addI15dLabel(String resourceKey, 139 String encodedConstraints) { 140 return addI15dLabel(resourceKey, 141 new CellConstraints(encodedConstraints)); 142 } 143 144 /** 145 * Adds an internationalized (i15d) label and component to the panel using 146 * the given cell constraints. Sets the label as <i>the</i> component label 147 * using {@link JLabel#setLabelFor(java.awt.Component)}.<p> 148 * 149 * <strong>Note:</strong> The {@link CellConstraints} objects for the label 150 * and the component must be different. Cell constraints are implicitly 151 * cloned by the <code>FormLayout</code> when added to the container. 152 * However, in this case you may be tempted to reuse a 153 * <code>CellConstraints</code> object in the same way as with many other 154 * builder methods that require a single <code>CellConstraints</code> 155 * parameter. 156 * The pitfall is that the methods <code>CellConstraints.xy**(...)</code> 157 * just set the coordinates but do <em>not</em> create a new instance. 158 * And so the second invocation of <code>xy***(...)</code> overrides 159 * the settings performed in the first invocation before the object 160 * is cloned by the <code>FormLayout</code>.<p> 161 * 162 * <strong>Wrong:</strong><pre> 163 * builder.add("name.key", 164 * cc.xy(1, 7), // will be modified by the code below 165 * nameField, 166 * cc.xy(3, 7) // sets the single instance to (3, 7) 167 * ); 168 * </pre> 169 * <strong>Correct:</strong><pre> 170 * builder.add("name.key", 171 * cc.xy(1, 7).clone(), // cloned before the next modification 172 * nameField, 173 * cc.xy(3, 7) // sets this instance to (3, 7) 174 * ); 175 * </pre> 176 * 177 * @param resourceKey the resource key for the label 178 * @param labelConstraints the label's cell constraints 179 * @param component the component to add 180 * @param componentConstraints the component's cell constraints 181 * @return the added label 182 * @exception IllegalArgumentException if the same cell constraints instance 183 * is used for the label and the component 184 * @see JLabel#setLabelFor(java.awt.Component) 185 */ 186 public final JLabel addI15dLabel(String resourceKey, 187 CellConstraints labelConstraints, Component component, 188 CellConstraints componentConstraints) { 189 190 return addLabel(getI15dString(resourceKey), labelConstraints, component, 191 componentConstraints); 192 } 193 194 /** 195 * Adds an internationalized (i15d) titled separator to the form using the 196 * specified constraints. 197 * 198 * @param resourceKey the resource key for the separator title 199 * @param constraints the separator's cell constraints 200 * @return the added titled separator 201 */ 202 public final JComponent addI15dSeparator(String resourceKey, 203 CellConstraints constraints) { 204 return addSeparator(getI15dString(resourceKey), constraints); 205 } 206 207 /** 208 * Adds an internationalized (i15d) titled separator to the form using 209 * the specified constraints. 210 * 211 * @param resourceKey the resource key for the separator title 212 * @param encodedConstraints a string representation for the constraints 213 * @return the added titled separator 214 */ 215 public final JComponent addI15dSeparator(String resourceKey, 216 String encodedConstraints) { 217 return addI15dSeparator(resourceKey, 218 new CellConstraints(encodedConstraints)); 219 } 220 221 /** 222 * Adds a title to the form using the specified constraints. 223 * 224 * @param resourceKey the resource key for the separator title 225 * @param constraints the separator's cell constraints 226 * @return the added title label 227 */ 228 public final JLabel addI15dTitle(String resourceKey, 229 CellConstraints constraints) { 230 return addTitle(getI15dString(resourceKey), constraints); 231 } 232 233 /** 234 * Adds a title to the form using the specified constraints. 235 * 236 * @param resourceKey the resource key for the separator title 237 * @param encodedConstraints a string representation for the constraints 238 * @return the added title label 239 */ 240 public final JLabel add15dTitle(String resourceKey, 241 String encodedConstraints) { 242 return addI15dTitle(resourceKey, 243 new CellConstraints(encodedConstraints)); 244 } 245 246 // Helper Code ********************************************************** 247 248 /** 249 * Looks up and returns the internationalized (i15d) string for the given 250 * resource key from the <code>ResourceBundle</code>. 251 * 252 * @param resourceKey the key to look for in the resource bundle 253 * @return the associated internationalized string, or the resource key 254 * itself in case of a missing resource 255 * @exception IllegalStateException if no <code>ResourceBundle</code> 256 * has been set 257 */ 258 protected String getI15dString(String resourceKey) { 259 if (bundle == null) { 260 throw new IllegalStateException("You must specify a ResourceBundle" 261 + " before using the internationalization support."); 262 } 263 try { 264 return bundle.getString(resourceKey); 265 } catch (MissingResourceException mre) { 266 return resourceKey; 267 } 268 } 269 270}