001    /* MultiTabbedPaneUI.java --
002       Copyright (C) 2005 Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    package javax.swing.plaf.multi;
039    
040    import java.awt.Dimension;
041    import java.awt.Graphics;
042    import java.awt.Rectangle;
043    import java.util.Iterator;
044    import java.util.Vector;
045    
046    import javax.accessibility.Accessible;
047    import javax.swing.JComponent;
048    import javax.swing.JTabbedPane;
049    import javax.swing.LookAndFeel;
050    import javax.swing.UIManager;
051    import javax.swing.plaf.ComponentUI;
052    import javax.swing.plaf.TabbedPaneUI;
053    
054    /**
055     * A UI delegate that that coordinates multiple {@link TabbedPaneUI}
056     * instances, one from the primary look and feel, and one or more from the
057     * auxiliary look and feel(s).
058     *
059     * @see UIManager#addAuxiliaryLookAndFeel(LookAndFeel)
060     */
061    public class MultiTabbedPaneUI extends TabbedPaneUI
062    {
063    
064      /** A list of references to the actual component UIs. */
065      protected Vector uis;
066    
067      /**
068       * Creates a new <code>MultiTabbedPaneUI</code> instance.
069       *
070       * @see #createUI(JComponent)
071       */
072      public MultiTabbedPaneUI()
073      {
074        uis = new Vector();
075      }
076    
077      /**
078       * Creates a delegate object for the specified component.  If any auxiliary
079       * look and feels support this component, a <code>MultiTabbedPaneUI</code> is
080       * returned, otherwise the UI from the default look and feel is returned.
081       *
082       * @param target  the component.
083       *
084       * @see MultiLookAndFeel#createUIs(ComponentUI, Vector, JComponent)
085       */
086      public static ComponentUI createUI(JComponent target)
087      {
088        MultiTabbedPaneUI mui = new MultiTabbedPaneUI();
089        return MultiLookAndFeel.createUIs(mui, mui.uis, target);
090      }
091    
092      /**
093       * Calls the {@link ComponentUI#installUI(JComponent)} method for all
094       * the UI delegates managed by this <code>MultiTabbedPaneUI</code>.
095       *
096       * @param c  the component.
097       */
098      public void installUI(JComponent c)
099      {
100        Iterator iterator = uis.iterator();
101        while (iterator.hasNext())
102        {
103          ComponentUI ui = (ComponentUI) iterator.next();
104          ui.installUI(c);
105        }
106      }
107    
108      /**
109       * Calls the {@link ComponentUI#uninstallUI(JComponent)} method for all
110       * the UI delegates managed by this <code>MultiTabbedPaneUI</code>.
111       *
112       * @param c  the component.
113       */
114      public void uninstallUI(JComponent c)
115      {
116        Iterator iterator = uis.iterator();
117        while (iterator.hasNext())
118        {
119          ComponentUI ui = (ComponentUI) iterator.next();
120          ui.uninstallUI(c);
121        }
122      }
123    
124      /**
125       * Returns an array containing the UI delegates managed by this
126       * <code>MultiTabbedPaneUI</code>.  The first item in the array is always
127       * the UI delegate from the installed default look and feel.
128       *
129       * @return An array of UI delegates.
130       */
131      public ComponentUI[] getUIs()
132      {
133        return MultiLookAndFeel.uisToArray(uis);
134      }
135    
136      /**
137       * Calls the {@link ComponentUI#contains(JComponent, int, int)} method for all
138       * the UI delegates managed by this <code>MultiTabbedPaneUI</code>,
139       * returning the result for the UI delegate from the primary look and
140       * feel.
141       *
142       * @param c  the component.
143       * @param x  the x-coordinate.
144       * @param y  the y-coordinate.
145       *
146       * @return <code>true</code> if the specified (x, y) coordinate falls within
147       *         the bounds of the component as rendered by the UI delegate in the
148       *         primary look and feel, and <code>false</code> otherwise.
149       */
150      public boolean contains(JComponent c, int x, int y)
151      {
152        boolean result = false;
153        Iterator iterator = uis.iterator();
154        // first UI delegate provides the return value
155        if (iterator.hasNext())
156          {
157            ComponentUI ui = (ComponentUI) iterator.next();
158            result = ui.contains(c, x, y);
159          }
160        // return values from auxiliary UI delegates are ignored
161        while (iterator.hasNext())
162          {
163            ComponentUI ui = (ComponentUI) iterator.next();
164            /* boolean ignored = */ ui.contains(c, x, y);
165          }
166        return result;
167      }
168    
169      /**
170       * Calls the {@link ComponentUI#update(Graphics, JComponent)} method for all
171       * the UI delegates managed by this <code>MultiTabbedPaneUI</code>.
172       *
173       * @param g  the graphics device.
174       * @param c  the component.
175       */
176      public void update(Graphics g, JComponent c)
177      {
178        Iterator iterator = uis.iterator();
179        while (iterator.hasNext())
180        {
181          ComponentUI ui = (ComponentUI) iterator.next();
182          ui.update(g, c);
183        }
184      }
185    
186      /**
187       * Calls the <code>paint(Graphics, JComponent)</code> method for all the UI
188       * delegates managed by this <code>MultiTabbedPaneUI</code>.
189       *
190       * @param g  the graphics device.
191       * @param c  the component.
192       */
193      public void paint(Graphics g, JComponent c)
194      {
195        Iterator iterator = uis.iterator();
196        while (iterator.hasNext())
197        {
198          ComponentUI ui = (ComponentUI) iterator.next();
199          ui.paint(g, c);
200        }
201      }
202    
203      /**
204       * Calls the {@link ComponentUI#getPreferredSize(JComponent)} method for all
205       * the UI delegates managed by this <code>MultiTabbedPaneUI</code>,
206       * returning the preferred size for the UI delegate from the primary look and
207       * feel.
208       *
209       * @param c  the component.
210       *
211       * @return The preferred size returned by the UI delegate from the primary
212       *         look and feel.
213       */
214      public Dimension getPreferredSize(JComponent c)
215      {
216        Dimension result = null;
217        Iterator iterator = uis.iterator();
218        // first UI delegate provides the return value
219        if (iterator.hasNext())
220          {
221            ComponentUI ui = (ComponentUI) iterator.next();
222            result = ui.getPreferredSize(c);
223          }
224        // return values from auxiliary UI delegates are ignored
225        while (iterator.hasNext())
226          {
227            ComponentUI ui = (ComponentUI) iterator.next();
228            /* Dimension ignored = */ ui.getPreferredSize(c);
229          }
230        return result;
231      }
232    
233      /**
234       * Calls the {@link ComponentUI#getMinimumSize(JComponent)} method for all
235       * the UI delegates managed by this <code>MultiTabbedPaneUI</code>,
236       * returning the minimum size for the UI delegate from the primary look and
237       * feel.
238       *
239       * @param c  the component.
240       *
241       * @return The minimum size returned by the UI delegate from the primary
242       *         look and feel.
243       */
244      public Dimension getMinimumSize(JComponent c)
245      {
246        Dimension result = null;
247        Iterator iterator = uis.iterator();
248        // first UI delegate provides the return value
249        if (iterator.hasNext())
250          {
251            ComponentUI ui = (ComponentUI) iterator.next();
252            result = ui.getMinimumSize(c);
253          }
254        // return values from auxiliary UI delegates are ignored
255        while (iterator.hasNext())
256          {
257            ComponentUI ui = (ComponentUI) iterator.next();
258            /* Dimension ignored = */ ui.getMinimumSize(c);
259          }
260        return result;
261      }
262    
263      /**
264       * Calls the {@link ComponentUI#getMaximumSize(JComponent)} method for all
265       * the UI delegates managed by this <code>MultiTabbedPaneUI</code>,
266       * returning the maximum size for the UI delegate from the primary look and
267       * feel.
268       *
269       * @param c  the component.
270       *
271       * @return The maximum size returned by the UI delegate from the primary
272       *         look and feel.
273       */
274      public Dimension getMaximumSize(JComponent c)
275      {
276        Dimension result = null;
277        Iterator iterator = uis.iterator();
278        // first UI delegate provides the return value
279        if (iterator.hasNext())
280          {
281            ComponentUI ui = (ComponentUI) iterator.next();
282            result = ui.getMaximumSize(c);
283          }
284        // return values from auxiliary UI delegates are ignored
285        while (iterator.hasNext())
286          {
287            ComponentUI ui = (ComponentUI) iterator.next();
288            /* Dimension ignored = */ ui.getMaximumSize(c);
289          }
290        return result;
291      }
292    
293      /**
294       * Calls the {@link ComponentUI#getAccessibleChildrenCount(JComponent)} method
295       * for all the UI delegates managed by this <code>MultiTabbedPaneUI</code>,
296       * returning the count for the UI delegate from the primary look and
297       * feel.
298       *
299       * @param c  the component.
300       *
301       * @return The count returned by the UI delegate from the primary
302       *         look and feel.
303       */
304      public int getAccessibleChildrenCount(JComponent c)
305      {
306        int result = 0;
307        Iterator iterator = uis.iterator();
308        // first UI delegate provides the return value
309        if (iterator.hasNext())
310          {
311            ComponentUI ui = (ComponentUI) iterator.next();
312            result = ui.getAccessibleChildrenCount(c);
313          }
314        // return values from auxiliary UI delegates are ignored
315        while (iterator.hasNext())
316          {
317            ComponentUI ui = (ComponentUI) iterator.next();
318            /* int ignored = */ ui.getAccessibleChildrenCount(c);
319          }
320        return result;
321      }
322    
323      /**
324       * Calls the {@link ComponentUI#getAccessibleChild(JComponent, int)} method
325       * for all the UI delegates managed by this <code>MultiTabbedPaneUI</code>,
326       * returning the child for the UI delegate from the primary look and
327       * feel.
328       *
329       * @param c  the component
330       * @param i  the child index.
331       *
332       * @return The child returned by the UI delegate from the primary
333       *         look and feel.
334       */
335      public Accessible getAccessibleChild(JComponent c, int i)
336      {
337        Accessible result = null;
338        Iterator iterator = uis.iterator();
339        // first UI delegate provides the return value
340        if (iterator.hasNext())
341          {
342            ComponentUI ui = (ComponentUI) iterator.next();
343            result = ui.getAccessibleChild(c, i);
344          }
345        // return values from auxiliary UI delegates are ignored
346        while (iterator.hasNext())
347          {
348            ComponentUI ui = (ComponentUI) iterator.next();
349            /* Accessible ignored = */ ui.getAccessibleChild(c, i);
350          }
351        return result;
352      }
353    
354      /**
355       * Calls the {@link TabbedPaneUI#tabForCoordinate(JTabbedPane, int, int)}
356       * method for all the UI delegates managed by this
357       * <code>MultiTabbedPaneUI</code>, returning the tab index for the UI
358       * delegate from the primary look and feel.
359       *
360       * @param pane  the tabbed pane.
361       * @param x  the x-coordinate.
362       * @param y  the y-coordinate.
363       *
364       * @return The tab index returned by the UI delegate from the primary
365       *         look and feel.
366       */
367      public int tabForCoordinate(JTabbedPane pane, int x, int y)
368      {
369        int result = 0;
370        Iterator iterator = uis.iterator();
371        // first UI delegate provides the return value
372        if (iterator.hasNext())
373          {
374            TabbedPaneUI ui = (TabbedPaneUI) iterator.next();
375            result = ui.tabForCoordinate(pane, x, y);
376          }
377        // return values from auxiliary UI delegates are ignored
378        while (iterator.hasNext())
379          {
380            TabbedPaneUI ui = (TabbedPaneUI) iterator.next();
381            /* int ignored = */ ui.tabForCoordinate(pane, x, y);
382          }
383        return result;
384      }
385    
386      /**
387       * Calls the {@link TabbedPaneUI#getTabBounds(JTabbedPane, int)}
388       * method for all the UI delegates managed by this
389       * <code>MultiTabbedPaneUI</code>, returning the bounds for the UI
390       * delegate from the primary look and feel.
391       *
392       * @param pane  the tabbed pane.
393       * @param index  the index.
394       *
395       * @return The bounds returned by the UI delegate from the primary
396       *         look and feel.
397       */
398      public Rectangle getTabBounds(JTabbedPane pane, int index)
399      {
400        Rectangle result = null;
401        Iterator iterator = uis.iterator();
402        // first UI delegate provides the return value
403        if (iterator.hasNext())
404          {
405            TabbedPaneUI ui = (TabbedPaneUI) iterator.next();
406            result = ui.getTabBounds(pane, index);
407          }
408        // return values from auxiliary UI delegates are ignored
409        while (iterator.hasNext())
410          {
411            TabbedPaneUI ui = (TabbedPaneUI) iterator.next();
412            /* int ignored = */ ui.getTabRunCount(pane);
413          }
414        return result;
415      }
416    
417      /**
418       * Calls the {@link TabbedPaneUI#getTabRunCount(JTabbedPane)}
419       * method for all the UI delegates managed by this
420       * <code>MultiTabbedPaneUI</code>, returning the nt for the UI
421       * delegate from the primary look and feel.
422       *
423       * @param pane  the tabbed pane.
424       *
425       * @return The count returned by the UI delegate from the primary
426       *         look and feel.
427       */
428      public int getTabRunCount(JTabbedPane pane)
429      {
430        int result = 0;
431        Iterator iterator = uis.iterator();
432        // first UI delegate provides the return value
433        if (iterator.hasNext())
434          {
435            TabbedPaneUI ui = (TabbedPaneUI) iterator.next();
436            result = ui.getTabRunCount(pane);
437          }
438        // return values from auxiliary UI delegates are ignored
439        while (iterator.hasNext())
440          {
441            TabbedPaneUI ui = (TabbedPaneUI) iterator.next();
442            /* int ignored = */ ui.getTabRunCount(pane);
443          }
444        return result;
445      }
446    
447    }