001/*
002 * $Id: JXTitledPanel.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.BorderLayout;
025import java.awt.Color;
026import java.awt.Container;
027import java.awt.Font;
028
029import javax.swing.BorderFactory;
030import javax.swing.JComponent;
031
032import org.jdesktop.beans.JavaBean;
033import org.jdesktop.swingx.painter.Painter;
034import org.jdesktop.swingx.plaf.LookAndFeelAddons;
035import org.jdesktop.swingx.plaf.TitledPanelAddon;
036import org.jdesktop.swingx.plaf.TitledPanelUI;
037
038/**
039 * A special type of Panel that has a Title section and a Content section.<br>
040 * The following properties can be set with the UIManager to change the look
041 * and feel of the JXTitledPanel:
042 * <ul>
043 * <li>JXTitledPanel.titleForeground</li>
044 * <li>JXTitledPanel.titleBackground</li>
045 * <li>JXTitledPanel.titleFont</li>
046 * <li>JXTitledPanel.titlePainter</li>
047 * <li>JXTitledPanel.captionInsets</li>
048 * <li>JXTitledPanel.rightDecorationInsets</li>
049 * <li>JXTitledPanel.leftDecorationInsets</li>
050 * </ul>
051 * 
052 * @author Richard Bair
053 * @author Nicola Ken Barozzi
054 * @author Jeanette Winzenburg
055 */
056@JavaBean
057public class JXTitledPanel extends JXPanel {
058
059    /**
060     * @see #getUIClassID // *
061     * @see #readObject
062     */
063    static public final String uiClassID = "TitledPanelUI";
064
065    public static final String LEFT_DECORATION = "JXTitledPanel.leftDecoration";
066
067    public static final String RIGHT_DECORATION = "JXTitledPanel.rightDecoration";
068
069    /**
070     * Initialization that would ideally be moved into various look and feel
071     * classes.
072     */
073    static {
074        LookAndFeelAddons.contribute(new TitledPanelAddon());
075    }
076
077    /**
078     * The text to use for the title
079     */
080    private String title = "";
081
082    /**
083     * The Font to use for the Title
084     */
085    private Font titleFont;
086
087    /**
088     * The foreground color to use for the Title (particularly for the text)
089     */
090    private Color titleForeground;
091
092    /**
093     * The ContentPanel. Whatever this container is will be displayed in the
094     * Content section
095     */
096    private Container contentPanel;
097    
098    /**
099     * The Painter to use for painting the title section of the JXTitledPanel
100     */
101    private Painter titlePainter;
102
103    /**
104     * Create a new JTitledPanel with an empty string for the title.
105     */
106    public JXTitledPanel() {
107        this(" ");
108    }
109
110    /**
111     * Create a new JTitledPanel with the given title as the title for the
112     * panel.
113     * 
114     * @param title
115     */
116    public JXTitledPanel(String title) {
117        this(title, createDefaultContainer());
118    }
119
120    /**
121     * Create a new JTitledPanel with the given String as the title, and the
122     * given Container as the content panel.
123     * 
124     * @param title
125     * @param content
126     */
127    public JXTitledPanel(String title, Container content) {
128        setTitle(title);
129        setContentContainer(content);
130    }
131
132    /**
133     * Returns the look and feel (L&F) object that renders this component.
134     * 
135     * @return the TitledPanelUI object that renders this component
136     */
137    @Override
138    public TitledPanelUI getUI() {
139        return (TitledPanelUI) ui;
140    }
141
142    /**
143     * Sets the look and feel (L&F) object that renders this component.
144     * 
145     * @param ui
146     *            the TitledPanelUI L&F object
147     * @see javax.swing.UIDefaults#getUI
148     * @beaninfo bound: true
149     *          hidden: true attribute: visualUpdate true
150     *     description: The UI object that implements the Component's LookAndFeel.
151     */
152    public void setUI(TitledPanelUI ui) {
153        super.setUI(ui);
154    }
155
156    /**
157     * Returns a string that specifies the name of the L&F class that renders
158     * this component.
159     * 
160     * @return "TitledPanelUI"
161     * @see JComponent#getUIClassID
162     * @see javax.swing.UIDefaults#getUI
163     * @beaninfo expert: true 
164     *      description: A string that specifies the name of the L&F class.
165     */
166    @Override
167    public String getUIClassID() {
168        return uiClassID;
169    }
170
171    /**
172     * Notification from the <code>UIManager</code> that the L&F has changed.
173     * Replaces the current UI object with the latest version from the
174     * <code>UIManager</code>.
175     * 
176     * @see javax.swing.JComponent#updateUI
177     */
178    @Override
179    public void updateUI() {
180        setUI((TitledPanelUI) LookAndFeelAddons
181                .getUI(this, TitledPanelUI.class));
182    }
183
184    /**
185     * Gets the title for this titled panel.
186     * 
187     * @return the currently displayed title
188     */
189    public String getTitle() {
190        return title;
191    }
192
193    /**
194     * Sets the title for this title panel.
195     * 
196     * @param title
197     *            the title to display
198     */
199    public void setTitle(String title) {
200        String oldTitle = this.title;
201        this.title = (title == null ? "" : title);
202        // JW: fix swingx #9 - missing/incorrect notification
203        // let standard notification handle
204        // NOTE - "getting" the new property in the fire method is
205        // intentional: there's no way of missing any transformations
206        // on the parameter to set (like above: setting a
207        // value depending on whether the input is null).
208        firePropertyChange("title", oldTitle, getTitle());
209    }
210
211    public Container getContentContainer() {
212        if (contentPanel == null) {
213            contentPanel = new JXPanel();
214            ((JXPanel) contentPanel).setBorder(BorderFactory
215                    .createEmptyBorder());
216            this.add(contentPanel, BorderLayout.CENTER);
217        }
218        return contentPanel;
219    }
220
221    public void setContentContainer(Container contentPanel) {
222        if (this.contentPanel != null) {
223            remove(this.contentPanel);
224        }
225        add(contentPanel, BorderLayout.CENTER);
226        this.contentPanel = contentPanel;
227    }
228
229    /**
230     * Adds the given JComponent as a decoration on the right of the title
231     * 
232     * @param decoration
233     */
234    public void setRightDecoration(JComponent decoration) {
235        JComponent old = getRightDecoration();
236        getUI().setRightDecoration(decoration);
237        firePropertyChange("rightDecoration", old, getRightDecoration());
238    }
239    
240    public JComponent getRightDecoration() {
241        return getUI().getRightDecoration();
242    }
243
244    /**
245     * Adds the given JComponent as a decoration on the left of the title
246     * 
247     * @param decoration
248     */
249    public void setLeftDecoration(JComponent decoration) {
250        JComponent old = getLeftDecoration();
251        getUI().setLeftDecoration(decoration);
252        firePropertyChange("leftDecoration", old, getLeftDecoration());
253    }
254    
255    public JComponent getLeftDecoration() {
256        return getUI().getLeftDecoration();
257    }
258    
259    public Font getTitleFont() {
260        return titleFont;
261    }
262
263    public void setTitleFont(Font titleFont) {
264        Font old = getTitleFont();
265        this.titleFont = titleFont;
266        firePropertyChange("titleFont", old, getTitleFont());
267    }
268
269    /**
270     * Set the Painter to use for painting the title section of the JXTitledPanel.
271     * This value may be null, which will cause the current look and feel to paint
272     * an appropriate look
273     *
274     * @param p The Painter to use. May be null
275     */
276    public void setTitlePainter(Painter p) {
277        Painter old = getTitlePainter();
278        this.titlePainter = p;
279        firePropertyChange("titlePainter", old, getTitlePainter());
280    }
281    
282    /**
283     * @return the Painter to use for painting the background of the title section
284     */
285    public Painter getTitlePainter() {
286        return titlePainter;
287    }
288
289    public Color getTitleForeground() {
290        return titleForeground;
291    }
292
293    public void setTitleForeground(Color titleForeground) {
294        Color old = getTitleForeground();
295        this.titleForeground = titleForeground;
296        firePropertyChange("titleForeground", old, getTitleForeground());
297    }
298    
299    private static Container createDefaultContainer() {
300        //TODO: All this default container creation stuff should be in the UI
301        //delegate. Not enough time at the moment for me to do this right.
302        JXPanel p = new JXPanel();
303        p.setOpaque(false);
304        return p;
305    }
306
307}