OSDN Git Service

libjava/
[pf3gnuchains/gcc-fork.git] / libjava / classpath / javax / swing / JToolBar.java
1 /* JToolBar.java --
2    Copyright (C) 2002, 2004, 2005, 2006,  Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath 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 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38
39 package javax.swing;
40
41 import java.awt.Component;
42 import java.awt.Container;
43 import java.awt.Dimension;
44 import java.awt.Graphics;
45 import java.awt.Insets;
46 import java.awt.LayoutManager;
47 import java.beans.PropertyChangeListener;
48
49 import javax.accessibility.Accessible;
50 import javax.accessibility.AccessibleContext;
51 import javax.accessibility.AccessibleRole;
52 import javax.accessibility.AccessibleStateSet;
53 import javax.swing.plaf.ToolBarUI;
54
55 /**
56  * JToolBar is a component that provides a toolbar to Swing programs. Users
57  * can add buttons (or actions that will be represented by JButtons) as well
58  * as other components to the JToolBar. JToolBars can be dragged in and out
59  * of their parent components. If the JToolBar is dragged out of the parent,
60  * then it will be displayed in its own RootPaneContainer. For dragging to
61  * work properly, JToolBars need to be placed in a Container that has a
62  * BorderLayout. That parent Container cannot have components in the NORTH,
63  * EAST, SOUTH,  or WEST components (that is not the JToolBar).
64  */
65 public class JToolBar extends JComponent implements SwingConstants, Accessible
66 {
67   /**
68    * Provides the accessibility features for the <code>JToolBar</code>
69    * component.
70    */
71   protected class AccessibleJToolBar extends AccessibleJComponent
72   {
73     private static final long serialVersionUID = -5516888265903814215L;
74
75     /**
76      * Creates a new <code>AccessibleJToolBar</code> instance.
77      */
78     protected AccessibleJToolBar()
79     {
80       // Nothing to do here.
81     }
82
83     /**
84      * Returns a set containing the current state of the {@link JToolBar} 
85      * component.  The current implementation simply calls the superclass.
86      *
87      * @return The accessible state set.
88      */
89     public AccessibleStateSet getAccessibleStateSet()
90     {
91       // running tests against the reference implementation, I was unable
92       // to find any state information that is set specifically by the
93       // tool bar...
94       return super.getAccessibleStateSet();
95     }
96
97     /**
98      * Returns the accessible role for the <code>JToolBar</code> component.
99      *
100      * @return {@link AccessibleRole#TOOL_BAR}.
101      */
102     public AccessibleRole getAccessibleRole()
103     {
104       return AccessibleRole.TOOL_BAR;
105     }
106   }
107
108   /**
109    * This is the private JToolBar layout manager.
110    */
111   private class DefaultToolBarLayout implements LayoutManager
112   {
113     /**
114      * This method is called when a new component is added to the container.
115      *
116      * @param name The name of the component added.
117      * @param comp The component that was added.
118      */
119     public void addLayoutComponent(String name, Component comp)
120     {
121       // Do nothing.
122     }
123
124     /**
125      * This method is called to lay out the given container  to position and
126      * size the child components.
127      *
128      * @param c The container to lay out.
129      *
130      * @throws Error DOCUMENT ME!
131      */
132     public void layoutContainer(Container c)
133     {
134       if (! (c instanceof JToolBar))
135         throw new Error("DefaultToolBarLayout can only be used on JToolBars.");
136       Insets insets = getInsets();
137       Insets margin = getMargin();
138       int middle;
139       if (margin != null)
140         {
141           insets.left += margin.left;
142           insets.top += margin.top;
143           insets.bottom += margin.bottom;
144           insets.right += margin.right;
145         }
146       Component[] components = c.getComponents();
147       Dimension tdims = c.getSize();
148       int start = 0;
149       Dimension pref;
150
151       if (getOrientation() == SwingUtilities.HORIZONTAL)
152         {
153           start += insets.left;
154           for (int i = 0; i < components.length; i++)
155             {
156               if (components[i] != null && components[i].isVisible())
157                 {
158                   pref = components[i].getPreferredSize();
159                   if (pref != null)
160                     {
161                       middle = (tdims.height - pref.height) / 2;
162                       components[i].setBounds(start, middle, pref.width,
163                                               pref.height);
164                       start += pref.width;
165                     }
166                 }
167             }
168         }
169       else
170         {
171           start += insets.top;
172           for (int i = 0; i < components.length; i++)
173             {
174               if (components[i] != null && components[i].isVisible())
175                 {
176                   pref = components[i].getPreferredSize();
177                   if (pref != null)
178                     {
179                       middle = (tdims.width - pref.width) / 2;
180                       components[i].setBounds(middle, start, pref.width,
181                                               pref.height);
182                       start += pref.height;
183                     }
184                 }
185             }
186         }
187     }
188
189     /**
190      * This method returns the minimum size of the given container given the
191      * child components.
192      *
193      * @param parent The container to measure.
194      *
195      * @return The minimum size of the given container.
196      */
197     public Dimension minimumLayoutSize(Container parent)
198     {
199       return preferredLayoutSize(parent);
200     }
201
202     /**
203      * This method returns the preferred size of the given container given the
204      * child components.
205      *
206      * @param parent The container to measure.
207      *
208      * @return The preferred size of the given container.
209      */
210     public Dimension preferredLayoutSize(Container parent)
211     {
212       int orientation = getOrientation();
213       Component[] components = getComponents();
214
215       int limit = 0;
216       int total = 0;
217       Dimension dims;
218
219       int w = 0;
220       int h = 0;
221
222       if (orientation == SwingConstants.HORIZONTAL)
223         {
224           for (int i = 0; i < components.length; i++)
225             {
226               dims = components[i].getPreferredSize();
227               if (dims != null)
228                 {
229                   if (dims.height > limit)
230                     limit = dims.height;
231                   total += dims.width;
232                 }
233             }
234           w = total;
235           h = limit;
236         }
237       else
238         {
239           for (int i = 0; i < components.length; i++)
240             {
241               dims = components[i].getPreferredSize();
242               if (dims != null)
243                 {
244                   if (dims.width > limit)
245                     limit = dims.width;
246                   total += dims.height;
247                 }
248             }
249           w = limit;
250           h = total;
251         }
252
253       Insets insets = getInsets();
254       w += insets.left + insets.right;
255       h += insets.top + insets.bottom;
256
257       Insets margin = getMargin();
258       if (margin != null)
259         {
260           w += margin.left + margin.right;
261           h += margin.top + margin.bottom;
262         }
263
264       return new Dimension(w, h);
265     }
266
267     /**
268      * This method is called when the given component  is removed from the
269      * container.
270      *
271      * @param comp The component removed.
272      */
273     public void removeLayoutComponent(Component comp)
274     {
275       // Do nothing.
276     }
277   }
278
279   /**
280    * This is an extension of JSeparator used in toolbars. Unlike JSeparator,
281    * nothing is painted for this Separator, it is only blank space that
282    * separates components.
283    */
284   public static class Separator extends JSeparator
285   {
286     /** DOCUMENT ME! */
287     private static final long serialVersionUID = -1656745644823105219L;
288
289     /**
290      * Creates a new Separator object.
291      */
292     public Separator()
293     {
294       super();
295     } // Separator()
296
297     /**
298      * Creates a new Separator object with the given size.
299      *
300      * @param size The size of the separator.
301      */
302     public Separator(Dimension size)
303     {
304       setPreferredSize(size);
305     } // Separator()
306
307     /**
308      * This method returns the String ID of the UI class of  Separator.
309      *
310      * @return The UI class' String ID.
311      */
312     public String getUIClassID()
313     {
314       return "ToolBarSeparatorUI";
315     } // getUIClassID()
316
317     /**
318      * This method returns the preferred size of the Separator.
319      *
320      * @return The preferred size of the Separator.
321      */
322     public Dimension getPreferredSize()
323     {
324       return super.getPreferredSize();
325     } // getPreferredSize()
326
327     /**
328      * This method returns the maximum size of the Separator.
329      *
330      * @return The maximum size of the Separator.
331      */
332     public Dimension getMaximumSize()
333     {
334       return super.getPreferredSize();
335     } // getMaximumSize()
336
337     /**
338      * This method returns the minimum size of the Separator.
339      *
340      * @return The minimum size of the Separator.
341      */
342     public Dimension getMinimumSize()
343     {
344       return super.getPreferredSize();
345     } // getMinimumSize()
346
347     /**
348      * This method returns the size of the Separator.
349      *
350      * @return The size of the Separator.
351      */
352     public Dimension getSeparatorSize()
353     {
354       return super.getPreferredSize();
355     } // getSeparatorSize()
356
357     /**
358      * This method sets the size of the Separator.
359      *
360      * @param size The new size of the Separator.
361      */
362     public void setSeparatorSize(Dimension size)
363     {
364       setPreferredSize(size);
365     } // setSeparatorSize()
366   } // Separator
367
368   /** DOCUMENT ME! */
369   private static final long serialVersionUID = -1269915519555129643L;
370
371   /** Whether the JToolBar paints its border. */
372   private transient boolean paintBorder = true;
373
374   /** The extra insets around the JToolBar. */
375   private transient Insets margin;
376
377   /** Whether the JToolBar can float (and be dragged around). */
378   private transient boolean floatable = true;
379
380   /** Whether the buttons will have rollover borders. */
381   private transient boolean rollover;
382
383   /** The orientation of the JToolBar. */
384   private int orientation = HORIZONTAL;
385
386   /**
387    * This method creates a new JToolBar object with horizontal orientation
388    * and no name.
389    */
390   public JToolBar()
391   {
392     this(null, HORIZONTAL);
393   } // JToolBar()
394
395   /**
396    * This method creates a new JToolBar with the given orientation and  no
397    * name.
398    *
399    * @param orientation JToolBar orientation (HORIZONTAL or VERTICAL)
400    */
401   public JToolBar(int orientation)
402   {
403     this(null, orientation);
404   } // JToolBar()
405
406   /**
407    * This method creates a new JToolBar object with the given name and
408    * horizontal orientation.
409    *
410    * @param name Name assigned to undocked tool bar.
411    */
412   public JToolBar(String name)
413   {
414     this(name, HORIZONTAL);
415   } // JToolBar()
416
417   /**
418    * This method creates a new JToolBar object with the given name and
419    * orientation.
420    *
421    * @param name Name assigned to undocked tool bar.
422    * @param orientation JToolBar orientation (HORIZONTAL or VERTICAL)
423    */
424   public JToolBar(String name, int orientation)
425   {
426     setName(name);
427     setOrientation(orientation);
428     setLayout(new DefaultToolBarLayout());
429     revalidate();
430     setOpaque(true);
431     updateUI();
432   }
433
434   /**
435    * This method adds a new JButton that performs the given Action to the
436    * JToolBar.
437    *
438    * @param action The Action to add to the JToolBar.
439    *
440    * @return The JButton that wraps the Action.
441    */
442   public JButton add(Action action)
443   {
444     JButton b = createActionComponent(action);
445     add(b);
446     return b;
447   } // add()
448
449   /**
450    * This method paints the border if the borderPainted property is true.
451    *
452    * @param graphics The graphics object to paint with.
453    */
454   protected void paintBorder(Graphics graphics)
455   {
456     if (paintBorder && isFloatable())
457       super.paintBorder(graphics);
458   } // paintBorder()
459
460   /**
461    * This method returns the UI class used to paint this JToolBar.
462    *
463    * @return The UI class for this JToolBar.
464    */
465   public ToolBarUI getUI()
466   {
467     return (ToolBarUI) ui;
468   } // getUI()
469
470   /**
471    * This method sets the UI used with the JToolBar.
472    *
473    * @param ui The UI used with the JToolBar.
474    */
475   public void setUI(ToolBarUI ui)
476   {
477     super.setUI(ui);
478   } // setUI()
479
480   /**
481    * This method resets the UI used to the Look and Feel defaults.
482    */
483   public void updateUI()
484   {
485     setUI((ToolBarUI) UIManager.getUI(this));
486   }
487
488   /**
489    * This method returns the String identifier for the UI class to the used
490    * with the JToolBar.
491    *
492    * @return The String identifier for the UI class.
493    */
494   public String getUIClassID()
495   {
496     return "ToolBarUI";
497   } // getUIClassID()
498
499   /**
500    * This method sets the rollover property for the JToolBar. In rollover
501    * mode, JButtons inside the JToolBar will only display their borders when
502    * the mouse is moving over them.
503    *
504    * @param b The new rollover property.
505    */
506   public void setRollover(boolean b)
507   {
508     if (b != rollover)
509       {
510         rollover = b;
511         firePropertyChange("rollover", ! rollover, rollover);
512         revalidate();
513         repaint();
514       }
515   }
516
517   /**
518    * This method returns the rollover property.
519    *
520    * @return The rollover property.
521    */
522   public boolean isRollover()
523   {
524     return rollover;
525   }
526
527   /**
528    * This method returns the index of the given component.
529    *
530    * @param component The component to find.
531    *
532    * @return The index of the given component.
533    */
534   public int getComponentIndex(Component component)
535   {
536     Component[] components = getComponents();
537     if (components == null)
538       return -1;
539
540     for (int i = 0; i < components.length; i++)
541       if (components[i] == component)
542         return i;
543
544     return -1;
545   } // getComponentIndex()
546
547   /**
548    * This method returns the component at the given index.
549    *
550    * @param index The index of the component.
551    *
552    * @return The component at the given index.
553    */
554   public Component getComponentAtIndex(int index)
555   {
556     return getComponent(index);
557   } // getComponentAtIndex()
558
559   /**
560    * This method returns the margin property.
561    *
562    * @return The margin property.
563    */
564   public Insets getMargin()
565   {
566     return margin;
567   } // getMargin()
568
569   /**
570    * This method sets the margin property. The margin property determines the
571    * extra space between the children components of the JToolBar and the
572    * border.
573    *
574    * @param margin The margin property.
575    */
576   public void setMargin(Insets margin)
577   {
578     if ((this.margin != null && margin == null)
579         || (this.margin == null && margin != null)
580         || (margin != null && this.margin != null
581         && (margin.left != this.margin.left
582         || margin.right != this.margin.right || margin.top != this.margin.top
583         || margin.bottom != this.margin.bottom)))
584       {
585         Insets oldMargin = this.margin;
586         this.margin = margin;
587         firePropertyChange("margin", oldMargin, this.margin);
588         revalidate();
589         repaint();
590       }
591   } // setMargin()
592
593   /**
594    * This method returns the borderPainted property.
595    *
596    * @return The borderPainted property.
597    */
598   public boolean isBorderPainted()
599   {
600     return paintBorder;
601   } // isBorderPainted()
602
603   /**
604    * This method sets the borderPainted property. If set to false, the border
605    * will not be painted.
606    *
607    * @param painted Whether the border will be painted.
608    */
609   public void setBorderPainted(boolean painted)
610   {
611     if (painted != paintBorder)
612       {
613         paintBorder = painted;
614         firePropertyChange("borderPainted", ! paintBorder,
615                            paintBorder);
616         repaint();
617       }
618   } // setBorderPainted()
619
620   /**
621    * This method returns the floatable property.
622    *
623    * @return The floatable property.
624    */
625   public boolean isFloatable()
626   {
627     return floatable;
628   } // isFloatable()
629
630   /**
631    * This method sets the floatable property. If set to false, the JToolBar
632    * cannot be dragged.
633    *
634    * @param floatable Whether the JToolBar can be dragged.
635    */
636   public void setFloatable(boolean floatable)
637   {
638     if (floatable != this.floatable)
639       {
640         this.floatable = floatable;
641         firePropertyChange("floatable", ! floatable, floatable);
642       }
643   } // setFloatable()
644
645   /**
646    * This method returns the orientation of the JToolBar.
647    *
648    * @return The orientation of the JToolBar.
649    */
650   public int getOrientation()
651   {
652     return orientation;
653   } // getOrientation()
654
655   /**
656    * This method sets the layout manager to be used with the JToolBar.
657    *
658    * @param mgr The Layout Manager used with the JToolBar.
659    */
660   public void setLayout(LayoutManager mgr)
661   {
662     super.setLayout(mgr);
663     revalidate();
664     repaint();
665   } // setLayout()
666
667   /**
668    * This method sets the orientation property for JToolBar.
669    *
670    * @param orientation The new orientation for JToolBar.
671    *
672    * @throws IllegalArgumentException If the orientation is not HORIZONTAL or
673    *         VERTICAL.
674    */
675   public void setOrientation(int orientation)
676   {
677     if (orientation != HORIZONTAL && orientation != VERTICAL)
678       throw new IllegalArgumentException(orientation
679                                          + " is not a legal orientation");
680     if (orientation != this.orientation)
681       {
682         int oldOrientation = this.orientation;
683         this.orientation = orientation;
684         firePropertyChange("orientation", oldOrientation, this.orientation);
685         revalidate();
686         repaint();
687       }
688   } // setOrientation()
689
690   /**
691    * This method adds a Separator of default size to the JToolBar.
692    */
693   public void addSeparator()
694   {
695     add(new Separator());
696   } // addSeparator()
697
698   /**
699    * This method adds a Separator with the given size to the JToolBar.
700    *
701    * @param size The size of the Separator.
702    */
703   public void addSeparator(Dimension size)
704   {
705     add(new Separator(size));
706   } // addSeparator()
707
708   /**
709    * This method is used to create JButtons which can be added to the JToolBar
710    * for the given action.
711    *
712    * @param action The action to create a JButton for.
713    *
714    * @return The JButton created from the action.
715    */
716   protected JButton createActionComponent(Action action)
717   {
718     return new JButton(action);
719   } // createActionComponent()
720
721   /**
722    * This method creates a pre-configured PropertyChangeListener which updates
723    * the control as changes are made to the Action. However, this is no
724    * longer the recommended way of adding Actions to Containers. As such,
725    * this method returns null.
726    *
727    * @param button The JButton to configure a PropertyChangeListener for.
728    *
729    * @return null.
730    */
731   protected PropertyChangeListener createActionChangeListener(JButton button)
732   {
733     // XXX: As specified, this returns null. But seems kind of strange, usually deprecated methods don't just return null, verify!
734     return null;
735   } // createActionChangeListener()
736
737   /**
738    * This method overrides Container's addImpl method. If a JButton is added,
739    * it is disabled.
740    *
741    * @param component The Component to add.
742    * @param constraints The Constraints placed on the component.
743    * @param index The index to place the Component at.
744    */
745   protected void addImpl(Component component, Object constraints, int index)
746   {
747     // XXX: Sun says disable button but test cases show otherwise.
748     super.addImpl(component, constraints, index);
749
750     // if we added a Swing Button then adjust this a little
751     if (component instanceof AbstractButton)
752       {
753         AbstractButton b = (AbstractButton) component;
754         b.setRolloverEnabled(rollover);
755       }
756
757   } // addImpl()
758
759   /**
760    * Returns a string describing the attributes for the <code>JToolBar</code>
761    * component, for use in debugging.  The return value is guaranteed to be 
762    * non-<code>null</code>, but the format of the string may vary between
763    * implementations.
764    *
765    * @return A string describing the attributes of the <code>JToolBar</code>.
766    */
767   protected String paramString()
768   {
769     StringBuffer sb = new StringBuffer(super.paramString());
770     sb.append(",floatable=").append(floatable);
771     sb.append(",margin=");
772     if (margin != null)
773       sb.append(margin);
774     sb.append(",orientation=");
775     if (orientation == HORIZONTAL)
776       sb.append("HORIZONTAL");
777     else
778       sb.append(VERTICAL);
779     sb.append(",paintBorder=").append(paintBorder);
780     return sb.toString();
781   }
782
783   /**
784    * Returns the object that provides accessibility features for this
785    * <code>JToolBar</code> component.
786    *
787    * @return The accessible context (an instance of {@link AccessibleJToolBar}).
788    */
789   public AccessibleContext getAccessibleContext()
790   {
791     if (accessibleContext == null)
792       accessibleContext = new AccessibleJToolBar();
793
794     return accessibleContext;
795   }
796 }