View Javadoc

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__ */