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