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