KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jgoodies > uif_lite > panel > SimpleInternalFrame


1 /*
2  * Copyright (c) 2000-2005 JGoodies Karsten Lentzsch. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * o Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  *
10  * o Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * o Neither the name of JGoodies Karsten Lentzsch nor the names of
15  * its contributors may be used to endorse or promote products derived
16  * from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */

30
31 package com.jgoodies.uif_lite.panel;
32
33 import java.awt.*;
34
35 import javax.swing.*;
36 import javax.swing.border.AbstractBorder JavaDoc;
37
38 import com.jgoodies.looks.LookUtils;
39
40 /**
41  * A <code>JPanel</code> subclass that has a drop shadow border and
42  * that provides a header with icon, title and tool bar.<p>
43  *
44  * This class can be used to replace the <code>JInternalFrame</code>,
45  * for use outside of a <code>JDesktopPane</code>.
46  * The <code>SimpleInternalFrame</code> is less flexible but often
47  * more usable; it avoids overlapping windows and scales well
48  * up to IDE size.
49  * Several customers have reported that they and their clients feel
50  * much better with both the appearance and the UI feel.<p>
51  *
52  * The SimpleInternalFrame provides the following bound properties:
53  * <i>frameIcon, title, toolBar, content, selected.</i><p>
54  *
55  * By default the SimpleInternalFrame is in <i>selected</i> state.
56  * If you don't do anything, multiple simple internal frames will
57  * be displayed as selected.
58  *
59  * @author Karsten Lentzsch
60  * @version $Revision: 1.8 $
61  *
62  * @see javax.swing.JInternalFrame
63  * @see javax.swing.JDesktopPane
64  */

65
66 public class SimpleInternalFrame extends JPanel {
67
68     private JLabel titleLabel;
69     private GradientPanel gradientPanel;
70     private JPanel headerPanel;
71     private boolean selected;
72     
73     
74     // Instance Creation ****************************************************
75

76     /**
77      * Constructs a SimpleInternalFrame with the specified title.
78      * The title is intended to be non-blank, or in other words
79      * should contain non-space characters.
80      *
81      * @param title the initial title
82      */

83     public SimpleInternalFrame(String JavaDoc title) {
84         this(null, title, null, null);
85     }
86     
87     
88     /**
89      * Constructs a SimpleInternalFrame with the specified
90      * icon, and title.
91      *
92      * @param icon the initial icon
93      * @param title the initial title
94      */

95     public SimpleInternalFrame(Icon icon, String JavaDoc title) {
96         this(icon, title, null, null);
97     }
98
99     
100     /**
101      * Constructs a SimpleInternalFrame with the specified
102      * title, tool bar, and content panel.
103      *
104      * @param title the initial title
105      * @param bar the initial tool bar
106      * @param content the initial content pane
107      */

108     public SimpleInternalFrame(String JavaDoc title, JToolBar bar, JComponent content) {
109         this(null, title, bar, content);
110     }
111     
112
113     /**
114      * Constructs a SimpleInternalFrame with the specified
115      * icon, title, tool bar, and content panel.
116      *
117      * @param icon the initial icon
118      * @param title the initial title
119      * @param bar the initial tool bar
120      * @param content the initial content pane
121      */

122     public SimpleInternalFrame(
123         Icon icon,
124         String JavaDoc title,
125         JToolBar bar,
126         JComponent content) {
127         super(new BorderLayout());
128         this.selected = false;
129         this.titleLabel = new JLabel(title, icon, SwingConstants.LEADING);
130         JPanel top = buildHeader(titleLabel, bar);
131
132         add(top, BorderLayout.NORTH);
133         if (content != null) {
134             setContent(content);
135         }
136         setBorder(new ShadowBorder());
137         setSelected(true);
138         updateHeader();
139     }
140
141     
142     // Public API ***********************************************************
143

144     /**
145      * Returns the frame's icon.
146      *
147      * @return the frame's icon
148      */

149     public Icon getFrameIcon() {
150         return titleLabel.getIcon();
151     }
152     
153
154     /**
155      * Sets a new frame icon.
156      *
157      * @param newIcon the icon to be set
158      */

159     public void setFrameIcon(Icon newIcon) {
160         Icon oldIcon = getFrameIcon();
161         titleLabel.setIcon(newIcon);
162         firePropertyChange("frameIcon", oldIcon, newIcon);
163     }
164     
165
166     /**
167      * Returns the frame's title text.
168      *
169      * @return String the current title text
170      */

171     public String JavaDoc getTitle() {
172         return titleLabel.getText();
173     }
174     
175     
176     /**
177      * Sets a new title text.
178      *
179      * @param newText the title text tp be set
180      */

181     public void setTitle(String JavaDoc newText) {
182         String JavaDoc oldText = getTitle();
183         titleLabel.setText(newText);
184         firePropertyChange("title", oldText, newText);
185     }
186     
187     
188     /**
189      * Returns the current toolbar, null if none has been set before.
190      *
191      * @return the current toolbar - if any
192      */

193     public JToolBar getToolBar() {
194         return headerPanel.getComponentCount() > 1
195             ? (JToolBar) headerPanel.getComponent(1)
196             : null;
197     }
198     
199
200     /**
201      * Sets a new tool bar in the header.
202      *
203      * @param newToolBar the tool bar to be set in the header
204      */

205     public void setToolBar(JToolBar newToolBar) {
206         JToolBar oldToolBar = getToolBar();
207         if (oldToolBar == newToolBar) {
208             return;
209         }
210         if (oldToolBar != null) {
211             headerPanel.remove(oldToolBar);
212         }
213         if (newToolBar != null) {
214             newToolBar.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
215             headerPanel.add(newToolBar, BorderLayout.EAST);
216         }
217         updateHeader();
218         firePropertyChange("toolBar", oldToolBar, newToolBar);
219     }
220
221     
222     /**
223      * Returns the content - null, if none has been set.
224      *
225      * @return the current content
226      */

227     public Component getContent() {
228         return hasContent() ? getComponent(1) : null;
229     }
230     
231     
232     /**
233      * Sets a new panel content; replaces any existing content, if existing.
234      *
235      * @param newContent the panel's new content
236      */

237     public void setContent(Component newContent) {
238         Component oldContent = getContent();
239         if (hasContent()) {
240             remove(oldContent);
241         }
242         add(newContent, BorderLayout.CENTER);
243         firePropertyChange("content", oldContent, newContent);
244     }
245     
246
247     /**
248      * Answers if the panel is currently selected (or in other words active)
249      * or not. In the selected state, the header background will be
250      * rendered differently.
251      *
252      * @return boolean a boolean, where true means the frame is selected
253      * (currently active) and false means it is not
254      */

255     public boolean isSelected() {
256         return selected;
257     }
258     
259     
260     /**
261      * This panel draws its title bar differently if it is selected,
262      * which may be used to indicate to the user that this panel
263      * has the focus, or should get more attention than other
264      * simple internal frames.
265      *
266      * @param newValue a boolean, where true means the frame is selected
267      * (currently active) and false means it is not
268      */

269     public void setSelected(boolean newValue) {
270         boolean oldValue = isSelected();
271         selected = newValue;
272         updateHeader();
273         firePropertyChange("selected", oldValue, newValue);
274     }
275     
276
277     // Building *************************************************************
278

279     /**
280      * Creates and answers the header panel, that consists of:
281      * an icon, a title label, a tool bar, and a gradient background.
282      *
283      * @param label the label to paint the icon and text
284      * @param bar the panel's tool bar
285      * @return the panel's built header area
286      */

287     private JPanel buildHeader(JLabel label, JToolBar bar) {
288         gradientPanel =
289             new GradientPanel(new BorderLayout(), getHeaderBackground());
290         label.setOpaque(false);
291
292         gradientPanel.add(label, BorderLayout.WEST);
293         gradientPanel.setBorder(BorderFactory.createEmptyBorder(3, 4, 3, 1));
294
295         headerPanel = new JPanel(new BorderLayout());
296         headerPanel.add(gradientPanel, BorderLayout.CENTER);
297         setToolBar(bar);
298         headerPanel.setBorder(new RaisedHeaderBorder());
299         headerPanel.setOpaque(false);
300         return headerPanel;
301     }
302
303     /**
304      * Updates the header.
305      */

306     private void updateHeader() {
307         gradientPanel.setBackground(getHeaderBackground());
308         gradientPanel.setOpaque(isSelected());
309         titleLabel.setForeground(getTextForeground(isSelected()));
310         headerPanel.repaint();
311     }
312     
313
314     /**
315      * Updates the UI. In addition to the superclass behavior, we need
316      * to update the header component.
317      */

318     public void updateUI() {
319         super.updateUI();
320         if (titleLabel != null) {
321             updateHeader();
322         }
323     }
324
325
326     // Helper Code **********************************************************
327

328     /**
329      * Checks and answers if the panel has a content component set.
330      *
331      * @return true if the panel has a content, false if it's empty
332      */

333     private boolean hasContent() {
334         return getComponentCount() > 1;
335     }
336     
337     /**
338      * Determines and answers the header's text foreground color.
339      * Tries to lookup a special color from the L&amp;F.
340      * In case it is absent, it uses the standard internal frame forground.
341      *
342      * @param isSelected true to lookup the active color, false for the inactive
343      * @return the color of the foreground text
344      */

345     protected Color getTextForeground(boolean isSelected) {
346         Color c =
347             UIManager.getColor(
348                 isSelected
349                     ? "SimpleInternalFrame.activeTitleForeground"
350                     : "SimpleInternalFrame.inactiveTitleForeground");
351         if (c != null) {
352             return c;
353         }
354         return UIManager.getColor(
355             isSelected
356                 ? "InternalFrame.activeTitleForeground"
357                 : "Label.foreground");
358
359     }
360
361     /**
362      * Determines and answers the header's background color.
363      * Tries to lookup a special color from the L&amp;F.
364      * In case it is absent, it uses the standard internal frame background.
365      *
366      * @return the color of the header's background
367      */

368     protected Color getHeaderBackground() {
369         Color c =
370             UIManager.getColor("SimpleInternalFrame.activeTitleBackground");
371         if (c != null)
372             return c;
373         if (LookUtils.IS_LAF_WINDOWS_XP_ENABLED)
374             c = UIManager.getColor("InternalFrame.activeTitleGradient");
375         return c != null
376             ? c
377             : UIManager.getColor("InternalFrame.activeTitleBackground");
378     }
379
380
381     // Helper Classes *******************************************************
382

383     // A custom border for the raised header pseudo 3D effect.
384
private static class RaisedHeaderBorder extends AbstractBorder JavaDoc {
385
386         private static final Insets INSETS = new Insets(1, 1, 1, 0);
387
388         public Insets getBorderInsets(Component c) { return INSETS; }
389
390         public void paintBorder(Component c, Graphics g,
391             int x, int y, int w, int h) {
392                 
393             g.translate(x, y);
394             g.setColor(UIManager.getColor("controlLtHighlight"));
395             g.fillRect(0, 0, w, 1);
396             g.fillRect(0, 1, 1, h-1);
397             g.setColor(UIManager.getColor("controlShadow"));
398             g.fillRect(0, h-1, w, 1);
399             g.translate(-x, -y);
400         }
401     }
402
403     // A custom border that has a shadow on the right and lower sides.
404
private static class ShadowBorder extends AbstractBorder JavaDoc {
405
406         private static final Insets INSETS = new Insets(1, 1, 3, 3);
407
408         public Insets getBorderInsets(Component c) { return INSETS; }
409
410         public void paintBorder(Component c, Graphics g,
411             int x, int y, int w, int h) {
412                 
413             Color shadow = UIManager.getColor("controlShadow");
414             if (shadow == null) {
415                 shadow = Color.GRAY;
416             }
417             Color lightShadow = new Color(shadow.getRed(),
418                                             shadow.getGreen(),
419                                             shadow.getBlue(),
420                                             170);
421             Color lighterShadow = new Color(shadow.getRed(),
422                                             shadow.getGreen(),
423                                             shadow.getBlue(),
424                                             70);
425             g.translate(x, y);
426             
427             g.setColor(shadow);
428             g.fillRect(0, 0, w - 3, 1);
429             g.fillRect(0, 0, 1, h - 3);
430             g.fillRect(w - 3, 1, 1, h - 3);
431             g.fillRect(1, h - 3, w - 3, 1);
432             // Shadow line 1
433
g.setColor(lightShadow);
434             g.fillRect(w - 3, 0, 1, 1);
435             g.fillRect(0, h - 3, 1, 1);
436             g.fillRect(w - 2, 1, 1, h - 3);
437             g.fillRect(1, h - 2, w - 3, 1);
438             // Shadow line2
439
g.setColor(lighterShadow);
440             g.fillRect(w - 2, 0, 1, 1);
441             g.fillRect(0, h - 2, 1, 1);
442             g.fillRect(w-2, h-2, 1, 1);
443             g.fillRect(w - 1, 1, 1, h - 2);
444             g.fillRect(1, h - 1, w - 2, 1);
445             g.translate(-x, -y);
446         }
447     }
448
449     // A panel with a horizontal gradient background.
450
private static class GradientPanel extends JPanel {
451         
452         private GradientPanel(LayoutManager lm, Color background) {
453             super(lm);
454             setBackground(background);
455         }
456
457         public void paintComponent(Graphics g) {
458             super.paintComponent(g);
459             if (!isOpaque()) {
460                 return;
461             }
462             Color control = UIManager.getColor("control");
463             int width = getWidth();
464             int height = getHeight();
465
466             Graphics2D g2 = (Graphics2D) g;
467             Paint storedPaint = g2.getPaint();
468             g2.setPaint(
469                 new GradientPaint(0, 0, getBackground(), width, 0, control));
470             g2.fillRect(0, 0, width, height);
471             g2.setPaint(storedPaint);
472         }
473     }
474
475 }
Popular Tags