001/* MultiTabbedPaneUI.java --
002   Copyright (C) 2005 Free Software Foundation, Inc.
003
004This file is part of GNU Classpath.
005
006GNU Classpath is free software; you can redistribute it and/or modify
007it under the terms of the GNU General Public License as published by
008the Free Software Foundation; either version 2, or (at your option)
009any later version.
010
011GNU Classpath is distributed in the hope that it will be useful, but
012WITHOUT ANY WARRANTY; without even the implied warranty of
013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014General Public License for more details.
015
016You should have received a copy of the GNU General Public License
017along with GNU Classpath; see the file COPYING.  If not, write to the
018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
01902110-1301 USA.
020
021Linking this library statically or dynamically with other modules is
022making a combined work based on this library.  Thus, the terms and
023conditions of the GNU General Public License cover the whole
024combination.
025
026As a special exception, the copyright holders of this library give you
027permission to link this library with independent modules to produce an
028executable, regardless of the license terms of these independent
029modules, and to copy and distribute the resulting executable under
030terms of your choice, provided that you also meet, for each linked
031independent module, the terms and conditions of the license of that
032module.  An independent module is a module which is not derived from
033or based on this library.  If you modify this library, you may extend
034this exception to your version of the library, but you are not
035obligated to do so.  If you do not wish to do so, delete this
036exception statement from your version. */
037
038package javax.swing.plaf.multi;
039
040import java.awt.Dimension;
041import java.awt.Graphics;
042import java.awt.Rectangle;
043import java.util.Iterator;
044import java.util.Vector;
045
046import javax.accessibility.Accessible;
047import javax.swing.JComponent;
048import javax.swing.JTabbedPane;
049import javax.swing.LookAndFeel;
050import javax.swing.UIManager;
051import javax.swing.plaf.ComponentUI;
052import 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 */
061public 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}