001    /*
002     * $Id: JXHeader.java 3100 2008-10-14 22:33:10Z rah003 $
003     *
004     * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005     * Santa Clara, California 95054, U.S.A. All rights reserved.
006     *
007     * This library is free software; you can redistribute it and/or
008     * modify it under the terms of the GNU Lesser General Public
009     * License as published by the Free Software Foundation; either
010     * version 2.1 of the License, or (at your option) any later version.
011     *
012     * This library is distributed in the hope that it will be useful,
013     * but WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015     * Lesser General Public License for more details.
016     *
017     * You should have received a copy of the GNU Lesser General Public
018     * License along with this library; if not, write to the Free Software
019     * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
020     */
021    
022    package org.jdesktop.swingx;
023    
024    import java.awt.Color;
025    import java.awt.Dimension;
026    import java.awt.Font;
027    import javax.swing.Icon;
028    import org.jdesktop.swingx.plaf.HeaderUI;
029    import org.jdesktop.swingx.plaf.HeaderAddon;
030    import org.jdesktop.swingx.plaf.LookAndFeelAddons;
031    
032    /**
033     * <p><code>JXHeader is a simple component consisting of a title, a description,
034     * and an icon. An example of such a component can be seen on
035     * <a href="http://jext.free.fr/header.png">Romain Guys ProgX website</a></p>
036     *
037     * <p><code>JXHeader</code> is a simple component that is also sufficiently
038     * configurable to be usable. The description area
039     * accepts HTML conforming to version 3.2 of the HTML standard. The icon, title,
040     * and description are all configurable. <code>JXHeader</code> itself extends
041     * {@link JXPanel}, providing translucency and painting delegates.</p>
042     *
043     * <p>If I were to reconstruct the ui shown in the above screenshot, I might
044     * do so like this:<br/>
045     * <pre><code>
046     *      JXHeader header = new JXHeader();
047     *      header.setTitle("Timing Framework Spline Editor");
048     *      header.setDescription("Drag control points in the display to change the " +
049     *          "shape of the spline\n" +
050     *          "Click the Copy Code button to generate the corresponding Java code.");
051     *      Icon icon = new ImageIcon(getClass().getResource("tools.png"));
052     *      header.setIcon(icon);
053     * </code></pre></p>
054     *
055     * Note: The HTML support doesn't exist yet. The UI delegate needs to discover whether
056     * the text supplied is HTML or not, and change the content type of the editor pane
057     * being used. The problem is that if "text/html" is always used, the font is wrong.
058     * This same situation will be found in other parts of the code (JXErrorPane, for instance),
059     * so this needs to be dealt with.
060     *
061     * <h2>Defaults</h2>
062     * <p>BasicHeaderUI uses the following UI defaults:
063     *  <ul>
064     *      <li><b>Header.defaultIcon:</b> The default icon to use when creating a new JXHeader.</li>
065     *  </ul>
066     * </p>
067     *
068     * @status REVIEWED
069     * @author rbair
070     * @author rah003
071     */
072    public class JXHeader extends JXPanel {
073        /**
074         * SerialVersionUID.
075         */
076        private static final long serialVersionUID = 3593838231433068954L;
077    
078        /**
079         * JXHeader pluggable UI key <i>HeaderUI</i>
080         */
081        public final static String uiClassID = "HeaderUI";
082    
083        // ensure at least the default ui is registered
084        static {
085            LookAndFeelAddons.contribute(new HeaderAddon());
086        }
087    
088        /**
089         * Specifies desired location of the icon relative to the title/description text.
090         */
091        public static enum IconPosition {
092            /**
093             * Positions icon left from the text.
094             */
095            LEFT,
096            /**
097             * Positions icon right from the text.
098             */
099            RIGHT
100        }
101        private String title;
102        private String description;
103        private Icon icon;
104        private Font titleFont;
105        private Font descriptionFont;
106        private Color titleForeground;
107        private Color descriptionForeground;
108        private IconPosition iconPosition = IconPosition.RIGHT;
109    
110        /** Creates a new instance of JXHeader */
111        public JXHeader() {
112        }
113    
114        /**
115         * Creates a new instance of JXHeader. PropertyChangeEvents are fired
116         * when the title and description properties are set.
117         *
118         * @param title specifies the title property for this JXHeader
119         * @param description specifies the description property for this JXHeader
120         */
121        public JXHeader(String title, String description) {
122            this(title, description, null);
123        }
124    
125        /** Creates a new instance of JXHeader. PropertyChangeEvents are fired
126         * when the title and description properties are set.
127         *
128         * @param title specifies the title property for this JXHeader
129         * @param description specifies the description property for this JXHeader
130         * @param icon specifies the icon property for this JXHeader
131         */
132        public JXHeader(String title, String description, Icon icon) {
133            setTitle(title);
134            setDescription(description);
135            setIcon(icon);
136        }
137    
138        //------------------------------------------------------------- UI Logic
139    
140        /**
141         * {@inheritDoc}
142         */
143        public HeaderUI getUI() {
144            return (HeaderUI)super.getUI();
145        }
146    
147        /**
148         * Sets the look and feel (L&F) object that renders this component.
149         *
150         * @param ui the HeaderUI L&F object
151         * @see javax.swing.UIDefaults#getUI
152         */
153        public void setUI(HeaderUI ui) {
154            super.setUI(ui);
155        }
156    
157        /**
158         * Returns the name of the L&F class that renders this component.
159         *
160         * @return the string {@link #uiClassID}
161         * @see javax.swing.JComponent#getUIClassID
162         * @see javax.swing.UIDefaults#getUI
163         */
164        public String getUIClassID() {
165            return uiClassID;
166        }
167    
168        /**
169         * Notification from the <code>UIManager</code> that the L&F has changed.
170         * Replaces the current UI object with the latest version from the
171         * <code>UIManager</code>.
172         *
173         * @see javax.swing.JComponent#updateUI
174         */
175        @Override
176        public void updateUI() {
177            setUI((HeaderUI) LookAndFeelAddons
178                    .getUI(this, HeaderUI.class));
179        }
180    
181        /**
182         * Sets the title to use. This may be either plain text, or a simplified
183         * version of HTML, as JLabel would use.
184         *
185         * @param title the Title. May be null.
186         */
187        public void setTitle(String title) {
188            String old = getTitle();
189            this.title = title;
190            firePropertyChange("title", old, getTitle());
191        }
192    
193        /**
194         * Gets the title. This may use HTML, such as
195         * that supported by JLabel (version 3.2 of the HTML spec).
196         * @return the title. May be null.
197         */
198        public String getTitle() {
199            return title;
200        }
201    
202        /**
203         * Sets the description for this header. This may use HTML, such as
204         * that supported by JLabel (version 3.2 of the HTML spec).
205         *
206         * @param description the description. May be null, may be HTML or plain text.
207         */
208        public void setDescription(String description) {
209            String old = getDescription();
210            this.description = description;
211            firePropertyChange("description", old, getDescription());
212        }
213    
214        /**
215         * Gets the description.
216         *
217         * @return description
218         */
219        public String getDescription() {
220            return description;
221        }
222    
223        /**
224         * Sets the icon to use for the header. It is generally recommended that this
225         * be an image 64x64 pixels in size, and that the icon have no gaps at the top.
226         *
227         * @param icon may be null
228         */
229        public void setIcon(Icon icon) {
230            Icon old = getIcon();
231            this.icon = icon;
232            firePropertyChange("icon", old, getIcon());
233        }
234    
235        /**
236         * Gets the icon.
237         *
238         * @return the Icon being used. May be null.
239         */
240        public Icon getIcon() {
241            return icon;
242        }
243    
244        /**
245         * Sets new font for both, title and description line of the header.
246         * @see javax.swing.JComponent#setFont(java.awt.Font)
247         */
248        @Override
249        public void setFont(Font font) {
250            super.setFont(font);
251            setTitleFont(font);
252            setDescriptionFont(font);
253        }
254    
255        /**
256         * Sets new font for title.
257         * @param font New title font.
258         */
259        public void setTitleFont(Font font) {
260            Font old = getTitleFont();
261            this.titleFont = font;
262            firePropertyChange("titleFont", old, getTitleFont());
263        }
264    
265        /**
266         * Gets title font.
267         *
268         * @return the Font being used. May be null.
269         */
270        public Font getTitleFont() {
271            return titleFont;
272        }
273    
274        /**
275         * Sets font for the description line of header.
276         * @param font New description font.
277         */
278        public void setDescriptionFont(Font font) {
279            Font old = getDescriptionFont();
280            this.descriptionFont = font;
281            firePropertyChange("descriptionFont", old, getDescriptionFont());
282        }
283    
284        /**
285         * Gets description font.
286         *
287         * @return the Font being used. May be null.
288         */
289        public Font getDescriptionFont() {
290            return descriptionFont;
291        }
292    
293        /**
294         * Gets current title foreground color.
295         * @return the Color used to paint title. May be null.
296         */
297        public Color getTitleForeground() {
298            return titleForeground;
299        }
300    
301        /**
302         * Sets title foreground color.
303         * @param titleForeground the Color to be used to paint title.
304         */
305        public void setTitleForeground(Color titleForeground) {
306            Color old = getTitleForeground();
307            this.titleForeground = titleForeground;
308            firePropertyChange("titleForeground", old, getTitleForeground());
309        }
310    
311        /**
312         * Gets current description foreground color.
313         * @return the Color used to paint description. May be null.
314         */
315        public Color getDescriptionForeground() {
316            return descriptionForeground;
317        }
318    
319        /**
320         * Sets description foreground color.
321         * @param descriptionForeground the Color to be used to paint description.
322         */
323        public void setDescriptionForeground(Color descriptionForeground) {
324            Color old = getDescriptionForeground();
325            this.descriptionForeground = descriptionForeground;
326            firePropertyChange("descriptionForeground", old, getDescriptionForeground());
327        }
328    
329        /**
330         * Gets current icon position. Default is RIGHT.
331         * @return Current Icon position.
332         */
333        public IconPosition getIconPosition() {
334            return iconPosition;
335        }
336    
337        /**
338         * Sets new Icon position. Position is relative to the text. Default value is RIGHT.
339         * @see #getIconPosition()
340         * @param iconPosition new desired icon position
341         */
342        public void setIconPosition(IconPosition iconPosition) {
343            IconPosition old = getIconPosition();
344            this.iconPosition = iconPosition;
345            firePropertyChange("iconPosition", old, getIconPosition());
346        }
347    
348        public Dimension getPreferredSize() {
349            Dimension s = super.getPreferredSize();
350            // TODO: hack for JXLabel issue ... see JXHeaderVisualCheck.interactiveCustomProperties();
351            s.width += 5;
352            return s;
353        }
354    }