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.Actions;
23  import com.cosylab.gui.components.util.ColorHelper;
24  import com.cosylab.gui.components.util.CosyUIElements;
25  
26  import java.awt.Color;
27  import java.awt.Component;
28  import java.awt.Container;
29  import java.awt.Dimension;
30  import java.awt.Font;
31  import java.awt.Graphics;
32  import java.awt.Insets;
33  import java.awt.LayoutManager;
34  import java.awt.event.ComponentAdapter;
35  import java.awt.event.ComponentEvent;
36  import java.awt.event.FocusAdapter;
37  import java.awt.event.FocusEvent;
38  import java.awt.event.KeyAdapter;
39  import java.awt.event.KeyEvent;
40  import java.awt.event.MouseAdapter;
41  import java.awt.event.MouseEvent;
42  
43  import java.beans.PropertyChangeEvent;
44  import java.beans.PropertyChangeListener;
45  
46  import java.util.ArrayList;
47  import java.util.Iterator;
48  
49  import javax.swing.AbstractButton;
50  import javax.swing.Action;
51  import javax.swing.Icon;
52  import javax.swing.JButton;
53  import javax.swing.JPanel;
54  import javax.swing.JToggleButton;
55  import javax.swing.border.Border;
56  import javax.swing.event.ChangeEvent;
57  import javax.swing.event.ChangeListener;
58  
59  
60  /**
61   * This is a <code>JComponent</code>, which is a combination of a label and a
62   * toolbar. It contains an <code>Icon</code> read-write property called
63   * <code>icon</code>,  which sets the icon to be displayed in the left part of
64   * the title bar. The <code>String</code> read-write property
65   * <code>title</code>, which is the text written to the right of the icon, and
66   * a set of <code>JButton</code> objects displayed on the right side of the
67   * title bar or below the label. <br>
68   * The default color of the title bar is retrieved from the {@link
69   * com.cosylab.gui.components.util.ColorHelper} class and can change with
70   * different virtual machines and L&Fs. Two different colors are used: focus
71   * color for the left start of the background gradient and textHighlight color
72   * for the right part. When the PanelTitleBar is not in active state, the
73   * whole bar is painted with the background color. The changes of state can be
74   * achieved by calling the <code>setActive() </code> method.
75   *
76   * @author <a href="mailto:miha.kadunc@cosylab.com">Miha Kadunc</a>
77   * @version $id$
78   *
79   * @see com.cosylab.gui.components.TitledPanel
80   */
81  public class PanelTitleBar extends JPanel
82  {
83  	private static final long serialVersionUID = 1L;
84  
85  	/** DOCUMENT ME! */
86  	public static final String ACTION_STICKY = "sticky";
87  
88  	/** DOCUMENT ME! */
89  	public static final String ACTION_VISIBLE = "visible";
90  	private Border pressedBorder = CosyUIElements.getPlainBorder(false);
91  	private Border overBorder = CosyUIElements.getPlainBorder(true);
92  	private static final String BUTTON_KEY = "com.cosylab.gui.components.PanelTitleBar Key For Buttons 2431";
93  	private GradientLabel title = null;
94  	private ArrayList<AbstractButton> buttons = null;
95  	private int selectedIndex = -1;
96  	private boolean mouseIn = false;
97  	private PanelTitleBarLayout titleBarLayout;
98  
99  	private class PanelTitleBarLayout implements LayoutManager
100 	{
101 		private int height = 38;
102 		private PanelTitleBar panel = null;
103 		private int panelWidth = 0;
104 		private int minWidth = 0;
105 		private int minHeight = 0;
106 
107 		/**
108 		 * Creates a new PanelTitleBarLayout object.
109 		 *
110 		 * @param height DOCUMENT ME!
111 		 */
112 		public PanelTitleBarLayout(int height)
113 		{
114 			setHeight(height);
115 		}
116 
117 		/**
118 		 * @see LayoutManager#addLayoutComponent(String, Component)
119 		 */
120 		public void addLayoutComponent(String name, Component comp)
121 		{
122 			reposition(true);
123 		}
124 
125 		/**
126 		 * @see LayoutManager#removeLayoutComponent(Component)
127 		 */
128 		public void removeLayoutComponent(Component comp)
129 		{
130 			if ((panel != null) && (panel.getButtonsList() != null)) {
131 				if (panel.getButtonsList().contains(comp)) {
132 					panel.getButtonsList().remove(comp);
133 				}
134 
135 				reposition(true);
136 			}
137 		}
138 
139 		/**
140 		 * @see LayoutManager#preferredLayoutSize(Container)
141 		 */
142 		public Dimension preferredLayoutSize(Container parent)
143 		{
144 			reposition(true);
145 
146 			if (panel == null) {
147 				return new Dimension(height, height);
148 			}
149 
150 			return new Dimension(panel.getTitleLabel().getPreferredSize().width
151 			    + panel.getButtonsList().size() * height
152 			    + panel.getInsets().left + panel.getInsets().right, minHeight);
153 		}
154 
155 		/**
156 		 * @see LayoutManager#minimumLayoutSize(Container)
157 		 */
158 		public Dimension minimumLayoutSize(Container parent)
159 		{
160 			reposition(true);
161 
162 			return new Dimension(minWidth, minHeight);
163 		}
164 
165 		/**
166 		 * @see LayoutManager#layoutContainer(Container)
167 		 */
168 		public void layoutContainer(Container parent)
169 		{
170 			if (panel == null) {
171 				panel = (PanelTitleBar)parent;
172 				panel.addComponentListener(new ComponentAdapter() {
173 						public void componentResized(ComponentEvent event)
174 						{
175 							int h = minHeight;
176 							reposition(false);
177 
178 							if (h != minHeight) {
179 								panelWidth = -1;
180 								panel.revalidate();
181 							}
182 						}
183 					});
184 				reposition(true);
185 			}
186 		}
187 
188 		private void reposition(boolean force)
189 		{
190 			if ((panel == null) || (panel.getTitleLabel() == null)) {
191 				return;
192 			}
193 
194 			if ((force) || (panel.getWidth() != panelWidth)) {
195 				panelWidth = panel.getWidth();
196 
197 				int titleWidth = panel.getTitleLabel().getPreferredSize().width;
198 				int numButtons = 0;
199 
200 				for (Iterator iterator = panel.getButtonsList().iterator();
201 				    iterator.hasNext();) {
202 					AbstractButton b = (AbstractButton)iterator.next();
203 
204 					if (!isVisible(b)) {
205 						continue;
206 					}
207 
208 					if (!isSticky(b)) {
209 						numButtons++;
210 					}
211 				}
212 
213 				int[] currX = new int[]{ 0, 0 };
214 				int[] currY = new int[]{ 1, 1 };
215 				int botIdx = 0;
216 
217 				if (((panelWidth - titleWidth - numButtons * height) < 0)
218 				    && (numButtons != 0)) {
219 					currY[1] = height - 1;
220 					botIdx = 1;
221 				}
222 
223 				currX[0] = panelWidth - height + 1;
224 				currX[1] = currX[0];
225 
226 				for (Iterator iterator = panel.getButtonsList().iterator();
227 				    iterator.hasNext();) {
228 					AbstractButton b = (AbstractButton)iterator.next();
229 
230 					if (!isVisible(b)) {
231 						b.setVisible(false);
232 					} else {
233 						b.setVisible(true);
234 
235 						if (isSticky(b)) {
236 							b.setBounds(currX[0], currY[0], height - 2,
237 							    height - 2);
238 							currX[0] = currX[0] - height + 2;
239 						} else {
240 							b.setBounds(currX[botIdx], currY[botIdx],
241 							    height - 2, height - 2);
242 							currX[botIdx] = currX[botIdx] - height + 2;
243 						}
244 					}
245 				}
246 
247 				titleWidth = currX[0] + height - 3;
248 				panel.getTitleLabel().setBounds(1, 1, titleWidth, height - 2);
249 				minHeight = currY[botIdx] + height - 1;
250 				panel.setMinimumSize(new Dimension(height, minHeight));
251 			}
252 		}
253 
254 		private boolean isSticky(AbstractButton b)
255 		{
256 			if (b.getAction() == null) {
257 				return false;
258 			}
259 
260 			Action act = b.getAction();
261 
262 			return act.getValue(ACTION_STICKY) == Boolean.TRUE;
263 		}
264 
265 		private boolean isVisible(AbstractButton b)
266 		{
267 			if (b.getAction() == null) {
268 				return b.isVisible();
269 			}
270 
271 			Action act = b.getAction();
272 
273 			return act.getValue(ACTION_VISIBLE) != Boolean.FALSE;
274 		}
275 
276 		int getHeight()
277 		{
278 			return height;
279 		}
280 
281 		void setHeight(int height)
282 		{
283 			this.height = height;
284 			reposition(true);
285 		}
286 	}
287 
288 	/**
289 	 * Constructs a <code>PanelTitleBar</code> with a defined height, a title
290 	 * and an icon.
291 	 *
292 	 * @param title The <code>String</code> that labels the title bar.
293 	 * @param icon The <code>Icon</code> which will be displayed in the left.
294 	 * @param height Height of the title bar and size of the buttons.
295 	 */
296 	public PanelTitleBar(String title, Icon icon, int height)
297 	{
298 		super();
299 		this.title = new GradientLabel(title);
300 
301 		if (icon != null) {
302 			this.title.setIcon(icon);
303 		}
304 
305 		buttons = new ArrayList<AbstractButton>(10);
306 		initialize(height);
307 	}
308 
309 	/**
310 	 * Constructs a <code>PanelTitleBar</code> with a title. The height is set
311 	 * to 24 points and there is no icon shown.
312 	 *
313 	 * @param title The <code>String</code> that labels the title bar.
314 	 */
315 	public PanelTitleBar(String title)
316 	{
317 		this(title, null, 24);
318 	}
319 
320 	/**
321 	 * Constructs a default empty <code>PanelTitleBar</code>.  The title bar is
322 	 * 24 points high, has no title or icon and contains no buttons.
323 	 */
324 	public PanelTitleBar()
325 	{
326 		this("");
327 	}
328 
329 	/**
330 	 * Gets the <code>title</code> property.
331 	 *
332 	 * @return Returns the <code>String</code> that labels this title bar.
333 	 */
334 	public String getTitle()
335 	{
336 		return title.getText();
337 	}
338 
339 	/**
340 	 * Sets the title property, which is displayed in the top-left area of this
341 	 * title bar.
342 	 *
343 	 * @param title The text to be shown as the title.
344 	 */
345 	public void setTitle(String title)
346 	{
347 		this.title.setText(title);
348 	}
349 
350 	private void setSelectedButton(AbstractButton button)
351 	{
352 		if ((selectedIndex > -1) && (selectedIndex < buttons.size())) {
353 			AbstractButton old = buttons.get(selectedIndex);
354 			old.setBorderPainted(old.isSelected());
355 			old.setOpaque(false);
356 		}
357 
358 		if (button != null) {
359 			button.setBorderPainted(true);
360 			button.setOpaque(true);
361 			selectedIndex = buttons.indexOf(button);
362 		} else {
363 			selectedIndex = -1;
364 		}
365 	}
366 
367 	/**
368 	 * Gets the <code>icon</code> property.
369 	 *
370 	 * @return Returns the <code>Icon</code> that is displayed by this title
371 	 *         bar.
372 	 */
373 	public Icon getIcon()
374 	{
375 		return title.getIcon();
376 	}
377 
378 	/**
379 	 * Sets the <code>icon</code> property. The <code>Icon</code> passed as the
380 	 * parameter to this method is displayed in the top left corner of this
381 	 * panel.
382 	 *
383 	 * @param icon the icon to be set.
384 	 *
385 	 * @see #setIcon(Icon)
386 	 */
387 	public void setIcon(Icon icon)
388 	{
389 		title.setIcon(icon);
390 	}
391 
392 	/**
393 	 * Adds an <code>AbstractButton</code> to this title bar. Note that all the
394 	 * user has to provide is the button's icon and an associated action. All
395 	 * the behaviour needed for the button to fit into the title bar will be
396 	 * added to the button by the <code>PanelTitleBar</code>.  The button will
397 	 * be resized to a square with the same size as the  height of the bar.
398 	 * Its background color will be changed  to that of the bar and the border
399 	 * will be removed.  Some mouse and keyboard sensitivity will be added to
400 	 * the button.
401 	 *
402 	 * @param index DOCUMENT ME!
403 	 * @param button The button to be added to the title bar.
404 	 *
405 	 * @see #removeButton(AbstractButton)
406 	 */
407 	public void addButton(int index, AbstractButton button)
408 	{
409 		final AbstractButton butt = button;
410 		buttons.add(index, butt);
411 
412 		if (butt.isSelected()) {
413 			butt.setBorder(pressedBorder);
414 		} else {
415 			butt.setBorder(overBorder);
416 		}
417 
418 		butt.setFocusable(false);
419 		butt.setBorderPainted(butt.isSelected());
420 		butt.setOpaque(false);
421 		butt.setBackground(getBackground());
422 		butt.addMouseListener(new MouseAdapter() {
423 				public void mouseEntered(MouseEvent event)
424 				{
425 					if (butt.isEnabled()) {
426 						setSelectedButton(butt);
427 					}
428 
429 					mouseIn = true;
430 				}
431 
432 				public void mouseExited(MouseEvent event)
433 				{
434 					setSelectedButton(null);
435 					mouseIn = false;
436 				}
437 
438 				/**
439 				 * @see java.awt.event.MouseAdapter#mousePressed(MouseEvent)
440 				 */
441 				public void mousePressed(MouseEvent e)
442 				{
443 					if (butt.isEnabled()) {
444 						butt.setBorder(pressedBorder);
445 
446 						if (pressedBorder != null) {
447 							butt.setBorderPainted(true);
448 						} else {
449 							butt.setBorderPainted(false);
450 						}
451 					}
452 				}
453 
454 				/**
455 				 * @see java.awt.event.MouseAdapter#mouseReleased(MouseEvent)
456 				 */
457 				public void mouseReleased(MouseEvent e)
458 				{
459 					if (butt.isSelected()) {
460 						butt.setBorder(pressedBorder);
461 
462 						if (pressedBorder != null) {
463 							butt.setBorderPainted(true);
464 						} else {
465 							butt.setBorderPainted(false);
466 						}
467 					} else {
468 						butt.setBorder(overBorder);
469 
470 						if (overBorder != null) {
471 							if (butt.isEnabled()) {
472 								butt.setBorderPainted(true);
473 							}
474 						} else {
475 							butt.setBorderPainted(false);
476 						}
477 					}
478 				}
479 			});
480 
481 		if (butt instanceof JToggleButton) {
482 			butt.addChangeListener(new ChangeListener() {
483 					/**
484 					 * @see com.cosylab.introspection.PropertyChangeAdapter#propertyChange(PropertyChangeEvent)
485 					 */
486 					public void stateChanged(ChangeEvent evt)
487 					{
488 						if (butt.isSelected()) {
489 							butt.setBorder(pressedBorder);
490 
491 							if (pressedBorder != null) {
492 								butt.setBorderPainted(true);
493 							} else {
494 								butt.setBorderPainted(false);
495 							}
496 						} else {
497 							butt.setBorder(overBorder);
498 
499 							if (overBorder != null) {
500 								butt.setBorderPainted(true);
501 							} else {
502 								butt.setBorderPainted(false);
503 							}
504 						}
505 					}
506 				});
507 		}
508 
509 		add(butt, "Button");
510 	}
511 
512 	/**
513 	 * Adds a button to this component.
514 	 *
515 	 * @param button
516 	 *
517 	 * @see #addActionButton(int, Action)
518 	 */
519 	public void addButton(AbstractButton button)
520 	{
521 		addButton(buttons.size(), button);
522 	}
523 
524 	/**
525 	 * Adds a button activating the specified action to the component at the
526 	 * index specified.
527 	 *
528 	 * @param index
529 	 * @param action
530 	 *
531 	 * @see #addButton(int, AbstractButton)
532 	 */
533 	public void addActionButton(int index, Action action)
534 	{
535 		if (buttons.contains(action.getValue(BUTTON_KEY))) {
536 			buttons.add(index, (AbstractButton) action.getValue(BUTTON_KEY));
537 			buttons.remove(action.getValue(BUTTON_KEY));
538 
539 			return;
540 		}
541 
542 		AbstractButton tempButt = Actions.createButton(action);
543 		tempButt.setText("");
544 		tempButt.setToolTipText((String)action.getValue(Action.NAME));
545 
546 		if (action.getValue(Action.SMALL_ICON) != null) {
547 			tempButt.setIcon((Icon)action.getValue(Action.SMALL_ICON));
548 		}
549 
550 		action.addPropertyChangeListener(new PropertyChangeListener() {
551 				public void propertyChange(PropertyChangeEvent evt)
552 				{
553 					if (evt.getPropertyName().equals(ACTION_VISIBLE)) {
554 						revalidate();
555 						repaint();
556 					}
557 				}
558 			});
559 
560 		addButton(index, tempButt);
561 		action.putValue(BUTTON_KEY, tempButt);
562 	}
563 
564 	/**
565 	 * Adds a button activating the specified action to the component.
566 	 *
567 	 * @param action
568 	 *
569 	 * @see #addButton(int, AbstractButton)
570 	 */
571 	public void addActionButton(Action action)
572 	{
573 		addActionButton(buttons.size(), action);
574 	}
575 
576 	/**
577 	 * Removes the specified button from this title bar.
578 	 *
579 	 * @param button The button to be removed.
580 	 */
581 	public void removeButton(AbstractButton button)
582 	{
583 		if (button != null) {
584 			remove(button);
585 			buttons.remove(button);
586 		}
587 	}
588 
589 	/**
590 	 * Returns <code>true</code> if this title  button contains specified
591 	 * button.
592 	 *
593 	 * @param button The button to be tested for containment
594 	 *
595 	 * @return <code>true</code> if button is on this title panel
596 	 */
597 	public boolean containsButton(AbstractButton button)
598 	{
599 		return buttons.contains(button);
600 	}
601 
602 	/**
603 	 * Removes the button connected to the specified action from this title
604 	 * bar.
605 	 *
606 	 * @param action The button to be removed.
607 	 */
608 	public void removeActionButton(Action action)
609 	{
610 		removeButton((JButton)action.getValue(BUTTON_KEY));
611 		revalidate();
612 		repaint();
613 	}
614 
615 	/**
616 	 * Returns <code>true</code> if this title  button contains specified
617 	 * action.
618 	 *
619 	 * @param action The action to be tested for containment
620 	 *
621 	 * @return <code>true</code> if action is on this title panel
622 	 */
623 	public boolean containsAction(Action action)
624 	{
625 		return containsButton((JButton)action.getValue(BUTTON_KEY));
626 	}
627 
628 	private void initialize(int heigth)
629 	{
630 		setOpaque(true);
631 		setBorder(CosyUIElements.getPlainBorder(true));
632 		setLayout(titleBarLayout = new PanelTitleBarLayout(heigth));
633 		setFocusable(true);
634 		addFocusListener(new FocusAdapter() {
635 				public void focusGained(FocusEvent event)
636 				{
637 					if (buttons.size() < 1) {
638 						setSelectedButton(null);
639 
640 						if (event.getOppositeComponent() == getFocusCycleRootAncestor()
641 						    .getFocusTraversalPolicy().getComponentAfter(getFocusCycleRootAncestor(),
642 						        PanelTitleBar.this)) {
643 							PanelTitleBar.this.transferFocusBackward();
644 						} else {
645 							PanelTitleBar.this.transferFocus();
646 						}
647 					} else {
648 						setSelectedButton(buttons.get(buttons.size() - 1));
649 					}
650 				}
651 
652 				public void focusLost(FocusEvent event)
653 				{
654 					if (!mouseIn) {
655 						setSelectedButton(null);
656 					}
657 				}
658 			});
659 		addKeyListener(new KeyAdapter() {
660 				public void keyPressed(KeyEvent event)
661 				{
662 					if (event.getKeyCode() == KeyEvent.VK_LEFT) {
663 						moveSelectedLeft();
664 					} else if (event.getKeyCode() == KeyEvent.VK_RIGHT) {
665 						moveSelectedRight();
666 					} else if (event.getKeyCode() == KeyEvent.VK_SPACE) {
667 						actionSelected();
668 					}
669 				}
670 			});
671 		getInsets().bottom = 0;
672 		getInsets().right = 0;
673 		getInsets().top = 0;
674 		getInsets().left = 0;
675 
676 		setBackground(ColorHelper.getTextHighlight());
677 		setBackgroundStart(ColorHelper.getFocus());
678 		title.setFont(title.getFont().deriveFont(Font.PLAIN));
679 		title.setBorder(new Border() {
680 				/**
681 				 * @see javax.swing.border.Border#isBorderOpaque()
682 				 */
683 				public boolean isBorderOpaque()
684 				{
685 					return false;
686 				}
687 
688 				/**
689 				 * @see javax.swing.border.Border#getBorderInsets(Component)
690 				 */
691 				public Insets getBorderInsets(Component c)
692 				{
693 					return new Insets(0, 4, 0, 0);
694 				}
695 
696 				/**
697 				 * @see javax.swing.border.Border#paintBorder(Component,
698 				 *      Graphics, int, int, int, int)
699 				 */
700 				public void paintBorder(Component c, Graphics g, int x, int y,
701 				    int width, int height)
702 				{
703 					// nothing to do
704 				}
705 			});
706 		title.setOpaque(true);
707 		add(title, "Title");
708 		revalidate();
709 		repaint();
710 	}
711 
712 	private void moveSelectedRight()
713 	{
714 		if (buttons.size() > 0) {
715 			int newIdx = selectedIndex;
716 			AbstractButton newButton;
717 
718 			do {
719 				newIdx--;
720 
721 				if (newIdx < 0) {
722 					newIdx = buttons.size() - 1;
723 				}
724 			} while (!((newButton = buttons.get(newIdx))
725 			    .isEnabled() || newIdx == selectedIndex));
726 
727 			setSelectedButton(newButton);
728 		}
729 	}
730 
731 	private void moveSelectedLeft()
732 	{
733 		if (buttons.size() > 0) {
734 			int newIdx = selectedIndex;
735 			AbstractButton newButton;
736 
737 			do {
738 				newIdx++;
739 
740 				if (newIdx >= buttons.size()) {
741 					newIdx = 0;
742 				}
743 			} while (!((newButton = buttons.get(newIdx))
744 			    .isEnabled() || newIdx == selectedIndex));
745 
746 			setSelectedButton(newButton);
747 		}
748 	}
749 
750 	private void actionSelected()
751 	{
752 		if ((selectedIndex > -1) && (selectedIndex < buttons.size())) {
753 			((JButton)buttons.get(selectedIndex)).doClick(100);
754 		}
755 	}
756 
757 	/**
758 	 * Sets the state of this title bar. If <code>active</code> parameter is
759 	 * true, the background will be changed to the Metal L&F's focus color,
760 	 * otherwise it will be changed to the window title background color.
761 	 *
762 	 * @param active The flag determining the state of the title bar.
763 	 */
764 	public void setActive(boolean active)
765 	{
766 		if (active) {
767 			title.setOpaque(true);
768 		} else {
769 			title.setOpaque(false);
770 		}
771 	}
772 
773 	/**
774 	 * DOCUMENT ME!
775 	 *
776 	 * @return DOCUMENT ME!
777 	 */
778 	public GradientLabel getTitleLabel()
779 	{
780 		return title;
781 	}
782 
783 	protected ArrayList getButtonsList()
784 	{
785 		return buttons;
786 	}
787 
788 	/**
789 	 * Returns the color used for active background.
790 	 *
791 	 * @return Color
792 	 */
793 	public Color getBackgroundStart()
794 	{
795 		return title.getBackgroundStart();
796 	}
797 
798 	/**
799 	 * Returns the color used for active background.
800 	 *
801 	 * @param c The color that should be used as the background for active
802 	 *        PanelTitleBar
803 	 */
804 	public void setBackgroundStart(Color c)
805 	{
806 		title.setBackgroundStart(c);
807 	}
808 
809 	/**
810 	 * Sets the background colors for the component.
811 	 *
812 	 * @param backgroundStart The color used for left part of the component
813 	 *        when active
814 	 * @param background The color used for right part of active background and
815 	 *        inactive background.
816 	 */
817 	public void setBackground(Color backgroundStart, Color background)
818 	{
819 		setBackground(background);
820 		title.setBackgroundStart(backgroundStart);
821 	}
822 
823 	/**
824 	 * Sets the background color of inactive title bar and the right color of
825 	 * an active title bar.
826 	 *
827 	 * @see #setBackgroundStart(Color)
828 	 */
829 	public void setBackground(Color c)
830 	{
831 		super.setBackground(c);
832 
833 		if (title != null) {
834 			title.setBackground(c);
835 		}
836 
837 		if (buttons != null) {
838 			for (Iterator iter = buttons.iterator(); iter.hasNext();) {
839 				AbstractButton element = (AbstractButton)iter.next();
840 				element.setBackground(c);
841 			}
842 		}
843 	}
844 
845 	/**
846 	 * DOCUMENT ME!
847 	 *
848 	 * @return Border
849 	 */
850 	public Border getOverBorder()
851 	{
852 		return overBorder;
853 	}
854 
855 	/**
856 	 * DOCUMENT ME!
857 	 *
858 	 * @return Border
859 	 */
860 	public Border getPressedBorder()
861 	{
862 		return pressedBorder;
863 	}
864 
865 	/**
866 	 * Sets the overBorder.
867 	 *
868 	 * @param overBorder The overBorder to set
869 	 */
870 	public void setOverBorder(Border overBorder)
871 	{
872 		this.overBorder = overBorder;
873 
874 		if (buttons != null) {
875 			for (Iterator iter = buttons.iterator(); iter.hasNext();) {
876 				AbstractButton element = (AbstractButton)iter.next();
877 
878 				if (!element.isSelected()) {
879 					element.setBorder(overBorder);
880 				}
881 			}
882 		}
883 	}
884 
885 	/**
886 	 * Sets the pressedBorder.
887 	 *
888 	 * @param pressedBorder The pressedBorder to set
889 	 */
890 	public void setPressedBorder(Border pressedBorder)
891 	{
892 		this.pressedBorder = pressedBorder;
893 
894 		if (buttons != null) {
895 			for (Iterator iter = buttons.iterator(); iter.hasNext();) {
896 				AbstractButton element = (AbstractButton)iter.next();
897 
898 				if (element.isSelected()) {
899 					element.setBorder(pressedBorder);
900 				}
901 			}
902 		}
903 	}
904 
905 	/**
906 	 * DOCUMENT ME!
907 	 *
908 	 * @param act
909 	 *
910 	 * @return
911 	 */
912 	public boolean hasAction(Action act)
913 	{
914 		AbstractButton[] buts = new AbstractButton[buttons.size()];
915 		buttons.toArray(buts);
916 
917 		for (int i = 0; i < buts.length; i++) {
918 			if (act.equals(buts[i].getAction())) {
919 				return true;
920 			}
921 		}
922 
923 		return false;
924 	}
925 
926 	/**
927 	 * Returns the higth of panel with the title bar.
928 	 *
929 	 * @return Returns the title bar height.
930 	 */
931 	public int getTitleBarHeight()
932 	{
933 		return titleBarLayout.getHeight();
934 	}
935 
936 	/**
937 	 * Sets the higth of panel with the title bar.
938 	 *
939 	 * @param titleBarHeight The title bar height to set.
940 	 */
941 	void setTitleBarHeight(int titleBarHeight)
942 	{
943 		titleBarLayout.setHeight(titleBarHeight);
944 	}
945 }
946 
947 /* __oOo__ */