Source Code Cross Referenced for DefaultComponentFactory.java in  » Swing-Library » jgoodies-forms » com » jgoodies » forms » factories » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Swing Library » jgoodies forms » com.jgoodies.forms.factories 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright (c) 2002-2007 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:
031:        package com.jgoodies.forms.factories;
032:
033:        import java.awt.*;
034:
035:        import javax.swing.*;
036:
037:        import com.jgoodies.forms.layout.Sizes;
038:        import com.jgoodies.forms.util.Utilities;
039:
040:        /**
041:         * A singleton implementaton of the {@link ComponentFactory} interface
042:         * that creates UI components as required by the 
043:         * {@link com.jgoodies.forms.builder.PanelBuilder}.<p>
044:         * 
045:         * The texts used in methods <code>#createLabel(String)</code> and 
046:         * <code>#createTitle(String)</code> can contain an optional mnemonic marker. 
047:         * The mnemonic and mnemonic index are indicated by a single ampersand 
048:         * (<tt>&amp;</tt>). For example <tt>&quot;&amp;Save&quot</tt>, 
049:         * or <tt>&quot;Save&nbsp;&amp;as&quot</tt>. To use the ampersand itself 
050:         * duplicate it, for example <tt>&quot;Look&amp;&amp;Feel&quot</tt>.
051:         *
052:         * @author Karsten Lentzsch
053:         * @version $Revision: 1.7 $
054:         */
055:        public class DefaultComponentFactory implements  ComponentFactory {
056:
057:            /**
058:             * Holds the single instance of this class.
059:             */
060:            private static final DefaultComponentFactory INSTANCE = new DefaultComponentFactory();
061:
062:            /** 
063:             * The character used to indicate the mnemonic position for labels. 
064:             */
065:            private static final char MNEMONIC_MARKER = '&';
066:
067:            // Instance *************************************************************
068:
069:            /**
070:             * Returns the sole instance of this factory class. 
071:             * 
072:             * @return the sole instance of this factory class
073:             */
074:            public static DefaultComponentFactory getInstance() {
075:                return INSTANCE;
076:            }
077:
078:            // Component Creation ***************************************************
079:
080:            /**
081:             * Creates and returns a label with an optional mnemonic.<p>
082:             * 
083:             * <pre>
084:             * createLabel("Name");       // No mnemonic
085:             * createLabel("N&ame");      // Mnemonic is 'a'
086:             * createLabel("Save &as");   // Mnemonic is the second 'a'
087:             * createLabel("Look&&Feel"); // No mnemonic, text is Look&Feel
088:             * </pre>
089:             * 
090:             * @param textWithMnemonic  the label's text - 
091:             *     may contain an ampersand (<tt>&amp;</tt>) to mark a mnemonic
092:             * @return an label with optional mnemonic
093:             */
094:            public JLabel createLabel(String textWithMnemonic) {
095:                JLabel label = new JLabel();
096:                setTextAndMnemonic(label, textWithMnemonic);
097:                return label;
098:            }
099:
100:            /**
101:             * Creates and returns a title label that uses the foreground color
102:             * and font of a <code>TitledBorder</code>.<p>
103:             * 
104:             * <pre>
105:             * createTitle("Name");       // No mnemonic
106:             * createTitle("N&ame");      // Mnemonic is 'a'
107:             * createTitle("Save &as");   // Mnemonic is the second 'a'
108:             * createTitle("Look&&Feel"); // No mnemonic, text is Look&Feel
109:             * </pre>
110:             * 
111:             * @param textWithMnemonic  the label's text - 
112:             *     may contain an ampersand (<tt>&amp;</tt>) to mark a mnemonic
113:             * @return an emphasized title label
114:             */
115:            public JLabel createTitle(String textWithMnemonic) {
116:                JLabel label = new TitleLabel();
117:                setTextAndMnemonic(label, textWithMnemonic);
118:                label.setVerticalAlignment(SwingConstants.CENTER);
119:                return label;
120:            }
121:
122:            /**
123:             * Creates and returns a labeled separator with the label in the left-hand
124:             * side. Useful to separate paragraphs in a panel; often a better choice 
125:             * than a <code>TitledBorder</code>.<p>
126:             * 
127:             * <pre>
128:             * createSeparator("Name");       // No mnemonic
129:             * createSeparator("N&ame");      // Mnemonic is 'a'
130:             * createSeparator("Save &as");   // Mnemonic is the second 'a'
131:             * createSeparator("Look&&Feel"); // No mnemonic, text is Look&Feel
132:             * </pre>
133:             * 
134:             * @param textWithMnemonic  the label's text - 
135:             *     may contain an ampersand (<tt>&amp;</tt>) to mark a mnemonic
136:             * @return a title label with separator on the side
137:             */
138:            public JComponent createSeparator(String textWithMnemonic) {
139:                return createSeparator(textWithMnemonic, SwingConstants.LEFT);
140:            }
141:
142:            /**
143:             * Creates and returns a labeled separator. Useful to separate 
144:             * paragraphs in a panel, which is often a better choice than a 
145:             * <code>TitledBorder</code>.<p>
146:             * 
147:             * <pre>
148:             * final int LEFT = SwingConstants.LEFT;
149:             * createSeparator("Name",       LEFT); // No mnemonic
150:             * createSeparator("N&ame",      LEFT); // Mnemonic is 'a'
151:             * createSeparator("Save &as",   LEFT); // Mnemonic is the second 'a'
152:             * createSeparator("Look&&Feel", LEFT); // No mnemonic, text is Look&Feel
153:             * </pre>
154:             * 
155:             * @param textWithMnemonic  the label's text - 
156:             *     may contain an ampersand (<tt>&amp;</tt>) to mark a mnemonic
157:             * @param alignment text alignment, one of <code>SwingConstants.LEFT</code>,
158:             *     <code>SwingConstants.CENTER</code>, <code>SwingConstants.RIGHT</code> 
159:             * @return a separator with title label 
160:             */
161:            public JComponent createSeparator(String textWithMnemonic,
162:                    int alignment) {
163:                if (textWithMnemonic == null || textWithMnemonic.length() == 0) {
164:                    return new JSeparator();
165:                }
166:                JLabel title = createTitle(textWithMnemonic);
167:                title.setHorizontalAlignment(alignment);
168:                return createSeparator(title);
169:            }
170:
171:            /**
172:             * Creates and returns a labeled separator. Useful to separate 
173:             * paragraphs in a panel, which is often a better choice than a 
174:             * <code>TitledBorder</code>.<p>
175:             * 
176:             * The label's position is determined by the label's horizontal alignment,
177:             * which must be one of: 
178:             * <code>SwingConstants.LEFT</code>,
179:             * <code>SwingConstants.CENTER</code>, 
180:             * <code>SwingConstants.RIGHT</code>.<p>
181:             * 
182:             * TODO: Since this method has been marked public in version 1.0.6,
183:             * we need to precisely describe the semantic of this method.<p>
184:             * 
185:             * TODO: Check if we can relax the constraint for the label alignment
186:             * and also accept LEADING and TRAILING.
187:             * 
188:             * @param label       the title label component
189:             * @return a separator with title label
190:             * 
191:             * @throws NullPointerException       if the label is <code>null</code> 
192:             * @throws IllegalArgumentException   if the label's horizontal alignment
193:             *      is not one of: <code>SwingConstants.LEFT</code>,
194:             *      <code>SwingConstants.CENTER</code>, 
195:             *      <code>SwingConstants.RIGHT</code>.
196:             * 
197:             * @since 1.0.6
198:             */
199:            public JComponent createSeparator(JLabel label) {
200:                if (label == null)
201:                    throw new NullPointerException(
202:                            "The label must not be null.");
203:                int horizontalAlignment = label.getHorizontalAlignment();
204:                if ((horizontalAlignment != SwingConstants.LEFT)
205:                        && (horizontalAlignment != SwingConstants.CENTER)
206:                        && (horizontalAlignment != SwingConstants.RIGHT))
207:                    throw new IllegalArgumentException(
208:                            "The label's horizontal alignment"
209:                                    + " must be one of: LEFT, CENTER, RIGHT.");
210:
211:                JPanel panel = new JPanel(new TitledSeparatorLayout(!Utilities
212:                        .isLafAqua()));
213:                panel.setOpaque(false);
214:                panel.add(label);
215:                panel.add(new JSeparator());
216:                if (horizontalAlignment == SwingConstants.CENTER) {
217:                    panel.add(new JSeparator());
218:                }
219:                return panel;
220:            }
221:
222:            // Helper Code ***********************************************************
223:
224:            /**
225:             * Sets the text of the given label and optionally a mnemonic.
226:             * The given text may contain an ampersand (<tt>&amp;</tt>)
227:             * to mark a mnemonic and its position. Such a marker indicates 
228:             * that the character that follows the ampersand shall be the mnemonic. 
229:             * If you want to use the ampersand itself duplicate it, for example 
230:             * <tt>&quot;Look&amp;&amp;Feel&quot</tt>.
231:             *  
232:             * @param label             the label that gets a mnemonic
233:             * @param textWithMnemonic  the text with optional mnemonic marker
234:             */
235:            private static void setTextAndMnemonic(JLabel label,
236:                    String textWithMnemonic) {
237:                int markerIndex = textWithMnemonic.indexOf(MNEMONIC_MARKER);
238:                // No marker at all
239:                if (markerIndex == -1) {
240:                    label.setText(textWithMnemonic);
241:                    return;
242:                }
243:                int mnemonicIndex = -1;
244:                int begin = 0;
245:                int end;
246:                int length = textWithMnemonic.length();
247:                int quotedMarkers = 0;
248:                StringBuffer buffer = new StringBuffer();
249:                do {
250:                    // Check whether the next index has a mnemonic marker, too
251:                    if ((markerIndex + 1 < length)
252:                            && (textWithMnemonic.charAt(markerIndex + 1) == MNEMONIC_MARKER)) {
253:                        end = markerIndex + 1;
254:                        quotedMarkers++;
255:                    } else {
256:                        end = markerIndex;
257:                        if (mnemonicIndex == -1) {
258:                            mnemonicIndex = markerIndex - quotedMarkers;
259:                        }
260:                    }
261:                    buffer.append(textWithMnemonic.substring(begin, end));
262:                    begin = end + 1;
263:                    markerIndex = begin < length ? textWithMnemonic.indexOf(
264:                            MNEMONIC_MARKER, begin) : -1;
265:                } while (markerIndex != -1);
266:                buffer.append(textWithMnemonic.substring(begin));
267:
268:                String text = buffer.toString();
269:                label.setText(text);
270:                if ((mnemonicIndex != -1) && (mnemonicIndex < text.length())) {
271:                    label.setDisplayedMnemonic(text.charAt(mnemonicIndex));
272:                    label.setDisplayedMnemonicIndex(mnemonicIndex);
273:                }
274:            }
275:
276:            /**
277:             * A label that uses the TitleBorder font and color.
278:             */
279:            private static final class TitleLabel extends JLabel {
280:
281:                private TitleLabel() {
282:                    // Just invoke the super constructor.
283:                }
284:
285:                /**
286:                 * TODO: For the Synth-based L&amp;f we should consider asking 
287:                 * a <code>TitledBorder</code> instance for its font and color using 
288:                 * <code>#getTitleFont</code> and <code>#getTitleColor</code> resp.
289:                 */
290:                public void updateUI() {
291:                    super .updateUI();
292:                    Color foreground = getTitleColor();
293:                    if (foreground != null) {
294:                        setForeground(foreground);
295:                    }
296:                    setFont(getTitleFont());
297:                }
298:
299:                private Color getTitleColor() {
300:                    return UIManager.getColor("TitledBorder.titleColor");
301:                }
302:
303:                /**
304:                 * Looks up and returns the font used for title labels.
305:                 * Since Mac Aqua uses an inappropriate titled border font,
306:                 * we use a bold label font instead. Actually if the title
307:                 * is used in a titled separator, the bold weight is questionable.
308:                 * It seems that most native Aqua tools use a plain label in
309:                 * titled separators.
310:                 * 
311:                 * @return the font used for title labels
312:                 */
313:                private Font getTitleFont() {
314:                    return Utilities.isLafAqua() ? UIManager.getFont(
315:                            "Label.font").deriveFont(Font.BOLD) : UIManager
316:                            .getFont("TitledBorder.font");
317:                }
318:
319:            }
320:
321:            /**
322:             * A layout for the title label and separator(s) in titled separators.
323:             */
324:            private static final class TitledSeparatorLayout implements 
325:                    LayoutManager {
326:
327:                private final boolean centerSeparators;
328:
329:                /**
330:                 * Constructs a TitledSeparatorLayout that either centers the separators
331:                 * or aligns them along the font baseline of the title label.
332:                 * 
333:                 * @param centerSeparators  true to center, false to align along
334:                 *     the font baseline of the title label
335:                 */
336:                private TitledSeparatorLayout(boolean centerSeparators) {
337:                    this .centerSeparators = centerSeparators;
338:                }
339:
340:                /**
341:                 * Does nothing. This layout manager looks up the components
342:                 * from the layout container and used the component's index
343:                 * in the child array to identify the label and separators.
344:                 * 
345:                 * @param name the string to be associated with the component
346:                 * @param comp the component to be added
347:                 */
348:                public void addLayoutComponent(String name, Component comp) {
349:                    // Does nothing.
350:                }
351:
352:                /**
353:                 * Does nothing. This layout manager looks up the components
354:                 * from the layout container and used the component's index
355:                 * in the child array to identify the label and separators.
356:                 * 
357:                 * @param comp the component to be removed
358:                 */
359:                public void removeLayoutComponent(Component comp) {
360:                    // Does nothing.
361:                }
362:
363:                /** 
364:                 * Computes and returns the minimum size dimensions 
365:                 * for the specified container. Forwards this request 
366:                 * to <code>#preferredLayoutSize</code>.
367:                 * 
368:                 * @param parent the component to be laid out
369:                 * @return the container's minimum size.
370:                 * @see #preferredLayoutSize(Container)
371:                 */
372:                public Dimension minimumLayoutSize(Container parent) {
373:                    return preferredLayoutSize(parent);
374:                }
375:
376:                /** 
377:                 * Computes and returns the preferred size dimensions 
378:                 * for the specified container. Returns the title label's
379:                 * preferred size.
380:                 * 
381:                 * @param parent the component to be laid out
382:                 * @return the container's preferred size.
383:                 * @see #minimumLayoutSize(Container)
384:                 */
385:                public Dimension preferredLayoutSize(Container parent) {
386:                    Component label = getLabel(parent);
387:                    Dimension labelSize = label.getPreferredSize();
388:                    Insets insets = parent.getInsets();
389:                    int width = labelSize.width + insets.left + insets.right;
390:                    int height = labelSize.height + insets.top + insets.bottom;
391:                    return new Dimension(width, height);
392:                }
393:
394:                /** 
395:                 * Lays out the specified container.
396:                 * 
397:                 * @param parent the container to be laid out 
398:                 */
399:                public void layoutContainer(Container parent) {
400:                    synchronized (parent.getTreeLock()) {
401:                        // Look up the parent size and insets
402:                        Dimension size = parent.getSize();
403:                        Insets insets = parent.getInsets();
404:                        int width = size.width - insets.left - insets.right;
405:
406:                        // Look up components and their sizes
407:                        JLabel label = getLabel(parent);
408:                        Dimension labelSize = label.getPreferredSize();
409:                        int labelWidth = labelSize.width;
410:                        int labelHeight = labelSize.height;
411:                        Component separator1 = parent.getComponent(1);
412:                        int separatorHeight = separator1.getPreferredSize().height;
413:
414:                        FontMetrics metrics = label.getFontMetrics(label
415:                                .getFont());
416:                        int ascent = metrics.getMaxAscent();
417:                        int hGapDlu = centerSeparators ? 3 : 1;
418:                        int hGap = Sizes.dialogUnitXAsPixel(hGapDlu, label);
419:                        int vOffset = centerSeparators ? 1 + (labelHeight - separatorHeight) / 2
420:                                : ascent - separatorHeight / 2;
421:
422:                        int alignment = label.getHorizontalAlignment();
423:                        int y = insets.top;
424:                        if (alignment == JLabel.LEFT) {
425:                            int x = insets.left;
426:                            label.setBounds(x, y, labelWidth, labelHeight);
427:                            x += labelWidth;
428:                            x += hGap;
429:                            int separatorWidth = size.width - insets.right - x;
430:                            separator1.setBounds(x, y + vOffset,
431:                                    separatorWidth, separatorHeight);
432:                        } else if (alignment == JLabel.RIGHT) {
433:                            int x = insets.left + width - labelWidth;
434:                            label.setBounds(x, y, labelWidth, labelHeight);
435:                            x -= hGap;
436:                            x--;
437:                            int separatorWidth = x - insets.left;
438:                            separator1.setBounds(insets.left, y + vOffset,
439:                                    separatorWidth, separatorHeight);
440:                        } else {
441:                            int xOffset = (width - labelWidth - 2 * hGap) / 2;
442:                            int x = insets.left;
443:                            separator1.setBounds(x, y + vOffset, xOffset - 1,
444:                                    separatorHeight);
445:                            x += xOffset;
446:                            x += hGap;
447:                            label.setBounds(x, y, labelWidth, labelHeight);
448:                            x += labelWidth;
449:                            x += hGap;
450:                            Component separator2 = parent.getComponent(2);
451:                            int separatorWidth = size.width - insets.right - x;
452:                            separator2.setBounds(x, y + vOffset,
453:                                    separatorWidth, separatorHeight);
454:                        }
455:                    }
456:                }
457:
458:                private JLabel getLabel(Container parent) {
459:                    return (JLabel) parent.getComponent(0);
460:                }
461:
462:            }
463:
464:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.