1 /*
2 * Copyright (c) 2003-2008 by Cosylab d. d.
3 *
4 * This file is part of CosyBeans-Common.
5 *
6 * CosyBeans-Common is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * CosyBeans-Common is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with CosyBeans-Common. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 package com.cosylab.gui.components;
21
22 import com.cosylab.gui.components.util.CosyUIElements;
23 import com.cosylab.gui.components.util.FontHelper;
24 import com.cosylab.gui.components.util.IconHelper;
25
26 import java.awt.BorderLayout;
27 import java.awt.Color;
28 import java.awt.Component;
29 import java.awt.Container;
30 import java.awt.Font;
31
32 import javax.swing.AbstractButton;
33 import javax.swing.Action;
34 import javax.swing.Icon;
35 import javax.swing.JComponent;
36 import javax.swing.JPanel;
37
38
39 /**
40 * TitledPanel is an extension of the Swing's JPanel, which contains a
41 * <code>PanelTitleBar</code> at the top. The rest of the panel's space is
42 * occupied by the <code>content</code> read-write property, which is an
43 * arbitrary <code>Component</code>. By default, the content property is set
44 * to <code>null</code>. <br>
45 * The title bar shows an <code>Icon</code> which is passed as a parameter to
46 * the constructor, and a <code>String</code> read-write property named
47 * title. Toolbar buttons can be added to the panel using the
48 * <code>addTitleBarButton()</code> method, passing a <code>JButton</code> as
49 * a parameter. The buttons added to the panel may be associated with an
50 * arbitrary action, which will not be affected by the TitledPanel.Note that
51 * buttons will not retain their original color, border or size after being
52 * added to the TitledPanel. <br>
53 * Width of the title bar (and thus also the size of the toolbar buttons) and
54 * the space between the panel's border and its content can both be
55 * determined when constructing the panel.
56 *
57 * @author <a href="mailto:miha.kadunc@cosylab.com">Miha Kadunc</a>
58 * @version $id$
59 *
60 * @see com.cosylab.gui.components.PanelTitleBar
61 * @see javax.swing.JPanel
62 */
63 public class TitledPanel extends JPanel
64 {
65 private static final long serialVersionUID = 1L;
66 protected PanelTitleBar bar = null;
67 private Container contentPane = null;
68
69 //private int toolBarHeight;
70 //private int borderWidth = 0;
71 private boolean initialized = false;
72
73 /**
74 * Constructor for TitledPanel. The name parameter is not visible in the
75 * panel, so it can be set to null. Title and Icon will be used for
76 * constructing the <code>PanelTitleBar</code>. The title bar will be
77 * created with the default width of 24 pixels and there will be no space
78 * between the border of the panel and its contents (titlebar and
79 * <code>content</code> component)
80 *
81 * @param name The name of the panel.
82 * @param title The title which will be displayed in the title bar.
83 * @param icon The icon to be rendered in the upper-left corner of the
84 * panel.
85 */
86 public TitledPanel(String name, String title, Icon icon)
87 {
88 this(name, title, icon, 20);
89 }
90
91 private TitledPanel(String name, PanelTitleBar bar)
92 {
93 super(new BorderLayout());
94 this.bar = bar;
95 setName(name);
96 }
97
98 /**
99 * Creates a new TitledPanel object.
100 */
101 public TitledPanel()
102 {
103 this("TitledPanel", "Title",
104 IconHelper.createIcon("icons/general/ComposeMail16.gif"));
105 }
106
107 /**
108 * Constructor for TitledPanel. The name parameter is not visible in the
109 * panel, so it can be set to null. Title and Icon will be used for
110 * constructing the <code>PanelTitleBar</code>.
111 *
112 * @param name The name of the panel.
113 * @param title The title which will be displayed in the title bar.
114 * @param icon The icon to be rendered in the upper-left corner of the
115 * panel.
116 * @param titleBarHeight Height of the title bar rendered in the top area
117 * of the panel.
118 */
119 public TitledPanel(String name, String title, Icon icon, int titleBarHeight)
120 {
121 this(name, new PanelTitleBar(title, icon, titleBarHeight));
122 }
123
124 /**
125 * Adds a <code>JButton</code> to this panel's title bar. Note that all the
126 * user has to provide is the button's icon and an associated action. All
127 * the behaviour needed for the button to fit into the title bar will be
128 * added to the button by the PanelTitleBar. The button will be resized
129 * to a square with the same size as the height of the bar. Its
130 * background color will be changed to that of the bar and the border
131 * will be removed. Some mouse and keyboard sensitivity will be added to
132 * the button.
133 *
134 * @param button The button to be added to the title bar.
135 */
136 public void addTitleBarButton(AbstractButton button)
137 {
138 bar.addButton(button);
139 }
140
141 /**
142 * Adds a button to this panel's title bar at specified index.
143 *
144 * @param index location of added button
145 * @param button
146 */
147 public void addTitleBarButton(int index, AbstractButton button)
148 {
149 bar.addButton(index, button);
150 }
151
152 /**
153 * Removes a button from this panel's title bar.
154 *
155 * @param button
156 */
157 public void removeTitleBarButton(AbstractButton button)
158 {
159 bar.removeButton(button);
160 }
161
162 /**
163 * Adds a button activating the specified action to this panel's title bar.
164 *
165 * @param action
166 */
167 public void addTitleBarAction(Action action)
168 {
169 bar.addActionButton(action);
170 }
171
172 /**
173 * Adds a button activating the specified action to this panel's title bar
174 * at specified index.
175 *
176 * @param index location of added action
177 * @param action
178 */
179 public void addTitleBarAction(int index, Action action)
180 {
181 bar.addActionButton(index, action);
182 }
183
184 /**
185 * @see PanelTitleBar#containsAction(Action)
186 */
187 public boolean containsTitleBarAction(Action action)
188 {
189 return bar.containsAction(action);
190 }
191
192 /**
193 * @see PanelTitleBar#containsButton(AbstractButton)
194 */
195 public boolean containsTitleBarAction(AbstractButton button)
196 {
197 return bar.containsButton(button);
198 }
199
200 /**
201 * Removes the button associated with the specified action from this
202 * panel's title bar.
203 *
204 * @param action
205 */
206 public void removeTitleBarAction(Action action)
207 {
208 bar.removeActionButton(action);
209 }
210
211 private void initialize()
212 {
213 initialized = true;
214 super.setFocusable(false);
215 bar.getTitleLabel().setFont(FontHelper.getDefaultFont());
216 bar.setVisible(true);
217
218 super.add(bar, BorderLayout.NORTH);
219 }
220
221 /**
222 * Sets this panel's title, which is diaplayed in the title bar. If the
223 * title is too long for the space which is available to the panel, it is
224 * trimmed and the missing parts are replaced by ...
225 *
226 * @param title The text that should be displayed as the title.
227 */
228 public void setTitle(String title)
229 {
230 bar.setTitle(title);
231 }
232
233 /**
234 * Gets the title.
235 *
236 * @return Returns the <code>String</code> displayed as the title.
237 *
238 * @see #getTitle
239 */
240 public String getTitle()
241 {
242 return bar.getTitle();
243 }
244
245 /**
246 * Returns the left background color of this panel's title bar.
247 *
248 * @return Color
249 */
250 public Color getTitleBackgroundLeft()
251 {
252 return bar.getBackgroundStart();
253 }
254
255 /**
256 * Gets the right background color of this panel's title bar.
257 *
258 * @return Color
259 */
260 public Color getTitleBackgroundRight()
261 {
262 return bar.getBackground();
263 }
264
265 /**
266 * Sets the background colors of this panel's title bar.
267 *
268 * @param left
269 * @param right
270 */
271 public void setTitleBackground(Color left, Color right)
272 {
273 if (left.equals(right)) {
274 bar.setBackground(right);
275 bar.getTitleLabel().setGradientEnabled(false);
276 } else {
277 bar.getTitleLabel().setGradientEnabled(true);
278 bar.setBackground(left, right);
279 }
280 }
281
282 /**
283 * Sets the background colors of this panel's title bar.
284 *
285 * @param left
286 */
287 public void setTitleBackgroundLeft(Color left)
288 {
289 bar.getTitleLabel().setGradientEnabled(true);
290 bar.setBackgroundStart(left);
291 }
292
293 /**
294 * Sets the background colors of this panel's title bar.
295 *
296 * @param right
297 */
298 public void setTitleBackgroundRight(Color right)
299 {
300 bar.getTitleLabel().setGradientEnabled(true);
301 bar.setBackground(right);
302 }
303
304 /**
305 * Return this panel's title bar icon.
306 *
307 * @return Icon
308 */
309 public Icon getIcon()
310 {
311 return bar.getIcon();
312 }
313
314 /**
315 * Sets the icon of this panel's title bar.
316 *
317 * @param icon
318 */
319 public void setIcon(Icon icon)
320 {
321 bar.setIcon(icon);
322 }
323
324 /**
325 * Gets the <code>content</code> Container.
326 *
327 * @return Returns the Component contained in this panel as the content
328 * pane.
329 */
330 public Container getContentPane()
331 {
332 if (contentPane == null) {
333 contentPane = new JPanel();
334 contentPane.setName(getName() + "ContentPane");
335 }
336
337 return contentPane;
338 }
339
340 /**
341 * Sets the content. The content is added to the panel below the title bar,
342 * covering all the available area.
343 *
344 * @param content The content to set
345 */
346 public void setContentPane(Container content)
347 {
348 if (!initialized) {
349 initialize();
350 }
351
352 if (this.contentPane != content) {
353 if (this.contentPane != null) {
354 remove(this.contentPane);
355 }
356
357 if ((content instanceof JComponent)
358 && (((JComponent)content).getBorder() == null)) {
359 ((JComponent)content).setBorder(CosyUIElements.getPlainBorder(
360 true));
361 }
362
363 this.contentPane = content;
364 super.add(content, BorderLayout.CENTER);
365 }
366
367 invalidate();
368 repaint();
369 }
370
371 protected GradientLabel getTitleBarLabel()
372 {
373 return bar.getTitleLabel();
374 }
375
376 /**
377 * Sets the visibility of the title bar.
378 *
379 * @param visible true if title bar is visible
380 */
381 public void setTitleBarVisible(boolean visible)
382 {
383 boolean old = bar.isVisible();
384
385 if (old != visible) {
386 bar.setVisible(visible);
387 firePropertyChange("titleBarVisible", old, visible);
388 revalidate();
389 repaint();
390 }
391 }
392
393 /**
394 * Returns true if title bar is visible or false otherwise.
395 *
396 * @return true if title bar is visible
397 */
398 public boolean isTitleBarVisible()
399 {
400 return bar.isVisible();
401 }
402
403 /*
404 * (non-Javadoc)
405 * @see java.awt.Container#add(java.awt.Component, int)
406 */
407 public Component add(Component comp, int index)
408 {
409 if (!initialized) {
410 initialize();
411 }
412
413 if (comp instanceof AbstractButton) {
414 addTitleBarButton((AbstractButton)comp);
415
416 return comp;
417 }
418
419 if (comp != bar && comp != contentPane) {
420 setContentPane((JComponent)comp);
421 }
422
423 return comp;
424 }
425
426 /*
427 * (non-Javadoc)
428 * @see java.awt.Container#add(java.awt.Component, java.lang.Object, int)
429 */
430 public void add(Component comp, Object constraints, int index)
431 {
432 if (!initialized) {
433 initialize();
434 }
435
436 if (comp instanceof AbstractButton) {
437 addTitleBarButton((AbstractButton)comp);
438
439 return;
440 }
441
442 if (comp != bar && comp != contentPane) {
443 setContentPane((JComponent)comp);
444 }
445 }
446
447 /*
448 * (non-Javadoc)
449 * @see java.awt.Container#add(java.awt.Component, java.lang.Object)
450 */
451 public void add(Component comp, Object constraints)
452 {
453 if (!initialized) {
454 initialize();
455 }
456
457 if (comp instanceof AbstractButton) {
458 addTitleBarButton((AbstractButton)comp);
459
460 return;
461 }
462
463 if (comp != bar && comp != contentPane) {
464 setContentPane((JComponent)comp);
465 }
466 }
467
468 /*
469 * (non-Javadoc)
470 * @see java.awt.Container#add(java.awt.Component)
471 */
472 public Component add(Component comp)
473 {
474 if (!initialized) {
475 initialize();
476 }
477
478 if (comp instanceof AbstractButton) {
479 addTitleBarButton((AbstractButton)comp);
480 } else if (comp != bar && comp != contentPane) {
481 setContentPane((JComponent)comp);
482 }
483
484 return comp;
485 }
486
487 /*
488 * (non-Javadoc)
489 * @see java.awt.Container#add(java.lang.String, java.awt.Component)
490 */
491 public Component add(String name, Component comp)
492 {
493 if (!initialized) {
494 initialize();
495 }
496
497 if (comp instanceof AbstractButton) {
498 addTitleBarButton((AbstractButton)comp);
499
500 return comp;
501 }
502
503 if (comp != bar && comp != contentPane) {
504 setContentPane((JComponent)comp);
505 }
506
507 return comp;
508 }
509
510 /*
511 * (non-Javadoc)
512 * @see javax.swing.JComponent#setFont(java.awt.Font)
513 */
514 public void setFont(Font font)
515 {
516 if (bar != null) {
517 bar.setFont(font);
518 }
519
520 super.setFont(font);
521 }
522
523 /*
524 * (non-Javadoc)
525 * @see javax.swing.JComponent#addNotify()
526 */
527 public void addNotify()
528 {
529 if (!initialized) {
530 initialize();
531 }
532
533 super.addNotify();
534 }
535
536 /*
537 * (non-Javadoc)
538 * @see java.awt.Container#remove(java.awt.Component)
539 */
540 public void remove(Component comp)
541 {
542 if (comp instanceof AbstractButton) {
543 removeTitleBarButton((AbstractButton)comp);
544
545 return;
546 }
547
548 super.remove(comp);
549 }
550 }
551
552 /* __oOo__ */