KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jgoodies > forms > factories > DefaultComponentFactory


1 /*
2  * Copyright (c) 2003 JGoodies Karsten Lentzsch. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * o Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  *
10  * o Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * o Neither the name of JGoodies Karsten Lentzsch nor the names of
15  * its contributors may be used to endorse or promote products derived
16  * from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */

30
31 package com.jgoodies.forms.factories;
32
33 import java.awt.Color JavaDoc;
34 import java.awt.GridBagConstraints JavaDoc;
35 import java.awt.GridBagLayout JavaDoc;
36 import java.lang.reflect.InvocationTargetException JavaDoc;
37 import java.lang.reflect.Method JavaDoc;
38
39 import javax.swing.*;
40
41 /**
42  * A singleton implementaton of the {@link ComponentFactory} interface
43  * that creates UI components as required by the
44  * {@link com.jgoodies.forms.builder.PanelBuilder}.
45  *
46  * @author Karsten Lentzsch
47  * @version $Revision: 1.4 $
48  */

49
50 public class DefaultComponentFactory implements ComponentFactory {
51     
52     /**
53      * Holds the single instance of this class.
54      */

55     private static final DefaultComponentFactory INSTANCE =
56         new DefaultComponentFactory();
57
58     /**
59      * Indicates whether this is a J2SE 1.2 or 1.3.
60      */

61     private static final boolean IS_BEFORE_14 = isBefore14();
62     
63     /**
64      * The character used to indicate the mnemonic position for labels.
65      */

66     private static final char MNEMONIC_MARKER = '&';
67         
68         
69     // Instance *************************************************************
70

71     private DefaultComponentFactory() {
72         // Suppresses default constructor, ensuring non-instantiability.
73
}
74     
75     /**
76      * Returns the sole instance of this factory class.
77      *
78      * @return the sole instance of this factory class
79      */

80     public static DefaultComponentFactory getInstance() {
81         return INSTANCE;
82     }
83     
84
85     // Component Creation ***************************************************
86

87     /**
88      * Creates and answers a label with an optional mnemonic.
89      *
90      * @param textWithMnemonic the label's text - may contain a mnemonic
91      * @return an label with optional mnemonic
92      */

93     public JLabel createLabel(String JavaDoc textWithMnemonic) {
94         JLabel label = new JLabel();
95         setTextAndMnemonic(label, textWithMnemonic);
96         return label;
97     }
98     
99     /**
100      * Creates and answers a label that uses the foreground color
101      * and font of a <code>TitledBorder</code>.
102      *
103      * @param textWithMnemonic the title's text - may contain a mnemonic
104      * @return an emphasized title label
105      */

106     public JLabel createTitle(String JavaDoc textWithMnemonic) {
107         return createTitle(textWithMnemonic, 0);
108     }
109     
110     /**
111      * Creates and answers a label that uses the foreground color
112      * and font of a <code>TitledBorder</code>.
113      *
114      * @param textWithMnemonic the title's text - may contain a mnemonic
115      * @param gap the right-hand side gap
116      * @return an emphasized title label
117      */

118     private JLabel createTitle(String JavaDoc textWithMnemonic, int gap) {
119         JLabel label = new TitleLabel();
120         setTextAndMnemonic(label, textWithMnemonic);
121         label.setVerticalAlignment(SwingConstants.CENTER);
122         label.setBorder(BorderFactory.createEmptyBorder(1, 0, 1, gap));
123         return label;
124     }
125
126     /**
127      * Creates and answers a label with separator on the left hand side.
128      * Useful to separate paragraphs in a panel. This is often a better choice
129      * than a <code>TitledBorder</code>.
130      * <p>
131      * The current implementation doesn't support component alignments.
132      *
133      * @param text the title's text
134      * @return a title label with separator on the side
135      */

136     public JComponent createSeparator(String JavaDoc text) {
137         return createSeparator(text, SwingConstants.LEFT);
138     }
139     
140     /**
141      * Creates and answers a label with separator; useful to separate
142      * paragraphs in a panel. This is often a better choice than
143      * a <code>TitledBorder</code>.
144      * <p>
145      * The current implementation doesn't support component alignments.
146      *
147      * @param text the title's text
148      * @param alignment text alignment: left, center, right
149      * @return a separator with title label
150      */

151     public JComponent createSeparator(String JavaDoc text, int alignment) {
152         JPanel header = new JPanel(new GridBagLayout JavaDoc());
153         GridBagConstraints JavaDoc gbc = new GridBagConstraints JavaDoc();
154         gbc.weightx = 0.0;
155         gbc.weighty = 1.0;
156         gbc.anchor = GridBagConstraints.SOUTHWEST;
157         gbc.fill = GridBagConstraints.BOTH;
158         gbc.gridwidth = 1;
159         gbc.gridheight = 3;
160         if (text != null && text.length() > 0) {
161             header.add(createTitle(text, 4), gbc);
162         }
163
164         gbc.weightx = 1.0;
165         gbc.weighty = 1.0;
166         gbc.gridwidth = GridBagConstraints.REMAINDER;
167         gbc.gridheight = 1;
168         JSeparator separator = new JSeparator();
169         header.add(Box.createGlue(), gbc);
170         gbc.weighty = 0.0;
171         header.add(separator, gbc);
172         gbc.weighty = 1.0;
173         header.add(Box.createGlue(), gbc);
174
175         return header;
176     }
177     
178     
179     // Helper Code ***********************************************************
180

181     /**
182      * Sets the text of the given label and optionally a mnemonic.
183      * The given text may contain mnemonic markers <b>&&</b>,
184      * where such a marker indicates that the following character
185      * shall be the mnemonic. If you want to use the <b>\&</b>
186      * charachter, just put two together, for example &quot;&&&&&quot;.
187      *
188      * @param label the label that gets a mnemonic
189      * @param textWithMnemonic the text with optional mnemonic marker
190      */

191     public static void setTextAndMnemonic(
192         JLabel label,
193         String JavaDoc textWithMnemonic) {
194         int markerIndex = textWithMnemonic.indexOf(MNEMONIC_MARKER);
195         // No marker at all
196
if (markerIndex == -1) {
197             label.setText(textWithMnemonic);
198             return;
199         }
200         int mnemonicIndex = -1;
201         int begin = 0;
202         int end;
203         int length = textWithMnemonic.length();
204         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
205         do {
206             // Check whether the next index has a mnemonic marker, too
207
if (markerIndex + 1 < length
208                 && textWithMnemonic.charAt(markerIndex + 1) == MNEMONIC_MARKER) {
209                 end = markerIndex + 1;
210             } else {
211                 end = markerIndex;
212                 if (mnemonicIndex == -1)
213                     mnemonicIndex = markerIndex;
214             }
215             buffer.append(textWithMnemonic.substring(begin, end));
216             begin = end + 1;
217             markerIndex = begin < length
218                 ? textWithMnemonic.indexOf(MNEMONIC_MARKER, begin)
219                 : -1;
220         } while (markerIndex != -1);
221         buffer.append(textWithMnemonic.substring(begin));
222
223         label.setText(buffer.toString());
224         if ((mnemonicIndex != -1) && (mnemonicIndex + 1 < length)) {
225             label.setDisplayedMnemonic(
226                 textWithMnemonic.charAt(mnemonicIndex + 1));
227             setDisplayedMnemonicIndex(label, mnemonicIndex);
228         }
229     }
230
231     /**
232      * Sets the displayed mnemonic index of the given label.
233      * In 1.4 environments we just delegate to
234      * <code>JLabel#setDisplayedMnemonicIndex</code>.
235      * In 1.3 environments the mnemonic index is set as
236      * a client property, so that a look can honor it
237      * - so do the JGoodies l&amp;fs.
238      * <p>
239      * TODO: Obsolete in 1.4
240      *
241      * @param label the label that gets a mnemonic
242      * @param displayedMnemonicIndex the index
243      */

244         private static void setDisplayedMnemonicIndex(JLabel label,
245             int displayedMnemonicIndex) {
246         Integer JavaDoc index = new Integer JavaDoc(displayedMnemonicIndex);
247         if (IS_BEFORE_14) {
248             label.putClientProperty("displayedMnemonicIndex", index);
249             return;
250         }
251         try {
252             Method JavaDoc method = AbstractButton.class.getMethod(
253                     "setDisplayedMnemonicIndex", new Class JavaDoc[]{});
254             method.invoke(label, new Integer JavaDoc[]{index});
255             return;
256         } catch (NoSuchMethodException JavaDoc e) {
257             // Likely we're not on 1.4; ignore
258
} catch (InvocationTargetException JavaDoc e) {
259             // Likely we're not on 1.4; ignore
260
} catch (IllegalAccessException JavaDoc e) {
261             // Likely we're not on 1.4; ignore
262
}
263     }
264     
265     /**
266      * Checks and answers whether this is a J2RE 1.2 or 1.3.
267      */

268     private static boolean isBefore14() {
269         String JavaDoc version = System.getProperty("java.version");
270         return version.startsWith("1.2") || version.startsWith("1.3");
271     }
272
273     // A label that uses the TitleBorder font and color
274
private static class TitleLabel extends JLabel {
275         
276         private TitleLabel() {
277             // Do nothing
278
}
279         
280         private TitleLabel(String JavaDoc text) {
281             super(text);
282         }
283         
284         public void updateUI() {
285             super.updateUI();
286             Color JavaDoc foreground =
287                 UIManager.getColor("TitledBorder.titleColor");
288             if (foreground != null)
289                 setForeground(foreground);
290             setFont(UIManager.getFont("TitledBorder.font"));
291         }
292         
293     }
294
295 }
Popular Tags