001/* MultiSplitPaneUI.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.util.Iterator;
043import java.util.Vector;
044
045import javax.accessibility.Accessible;
046import javax.swing.JComponent;
047import javax.swing.JSplitPane;
048import javax.swing.LookAndFeel;
049import javax.swing.UIManager;
050import javax.swing.plaf.ComponentUI;
051import javax.swing.plaf.SplitPaneUI;
052
053/**
054 * A UI delegate that that coordinates multiple {@link SplitPaneUI}
055 * instances, one from the primary look and feel, and one or more from the
056 * auxiliary look and feel(s).
057 *
058 * @see UIManager#addAuxiliaryLookAndFeel(LookAndFeel)
059 */
060public class MultiSplitPaneUI extends SplitPaneUI
061{
062
063  /** A list of references to the actual component UIs. */
064  protected Vector uis;
065
066  /**
067   * Creates a new <code>MultiSplitPaneUI</code> instance.
068   *
069   * @see #createUI(JComponent)
070   */
071  public MultiSplitPaneUI()
072  {
073    uis = new Vector();
074  }
075
076  /**
077   * Creates a delegate object for the specified component.  If any auxiliary
078   * look and feels support this component, a <code>MultiSplitPaneUI</code> is
079   * returned, otherwise the UI from the default look and feel is returned.
080   *
081   * @param target  the component.
082   *
083   * @see MultiLookAndFeel#createUIs(ComponentUI, Vector, JComponent)
084   */
085  public static ComponentUI createUI(JComponent target)
086  {
087    MultiSplitPaneUI mui = new MultiSplitPaneUI();
088    return MultiLookAndFeel.createUIs(mui, mui.uis, target);
089  }
090
091  /**
092   * Calls the {@link ComponentUI#installUI(JComponent)} method for all
093   * the UI delegates managed by this <code>MultiSplitPaneUI</code>.
094   *
095   * @param c  the component.
096   */
097  public void installUI(JComponent c)
098  {
099    Iterator iterator = uis.iterator();
100    while (iterator.hasNext())
101    {
102      ComponentUI ui = (ComponentUI) iterator.next();
103      ui.installUI(c);
104    }
105  }
106
107  /**
108   * Calls the {@link ComponentUI#uninstallUI(JComponent)} method for all
109   * the UI delegates managed by this <code>MultiSplitPaneUI</code>.
110   *
111   * @param c  the component.
112   */
113  public void uninstallUI(JComponent c)
114  {
115    Iterator iterator = uis.iterator();
116    while (iterator.hasNext())
117    {
118      ComponentUI ui = (ComponentUI) iterator.next();
119      ui.uninstallUI(c);
120    }
121  }
122
123  /**
124   * Returns an array containing the UI delegates managed by this
125   * <code>MultiSplitPaneUI</code>.  The first item in the array is always
126   * the UI delegate from the installed default look and feel.
127   *
128   * @return An array of UI delegates.
129   */
130  public ComponentUI[] getUIs()
131  {
132    return MultiLookAndFeel.uisToArray(uis);
133  }
134
135  /**
136   * Calls the {@link ComponentUI#contains(JComponent, int, int)} method for all
137   * the UI delegates managed by this <code>MultiSplitPaneUI</code>,
138   * returning the result for the UI delegate from the primary look and
139   * feel.
140   *
141   * @param c  the component.
142   * @param x  the x-coordinate.
143   * @param y  the y-coordinate.
144   *
145   * @return <code>true</code> if the specified (x, y) coordinate falls within
146   *         the bounds of the component as rendered by the UI delegate in the
147   *         primary look and feel, and <code>false</code> otherwise.
148   */
149  public boolean contains(JComponent c, int x, int y)
150  {
151    boolean result = false;
152    Iterator iterator = uis.iterator();
153    // first UI delegate provides the return value
154    if (iterator.hasNext())
155      {
156        ComponentUI ui = (ComponentUI) iterator.next();
157        result = ui.contains(c, x, y);
158      }
159    // return values from auxiliary UI delegates are ignored
160    while (iterator.hasNext())
161      {
162        ComponentUI ui = (ComponentUI) iterator.next();
163        /* boolean ignored = */ ui.contains(c, x, y);
164      }
165    return result;
166  }
167
168  /**
169   * Calls the {@link ComponentUI#update(Graphics, JComponent)} method for all
170   * the UI delegates managed by this <code>MultiSplitPaneUI</code>.
171   *
172   * @param g  the graphics device.
173   * @param c  the component.
174   */
175  public void update(Graphics g, JComponent c)
176  {
177    Iterator iterator = uis.iterator();
178    while (iterator.hasNext())
179    {
180      ComponentUI ui = (ComponentUI) iterator.next();
181      ui.update(g, c);
182    }
183  }
184
185  /**
186   * Calls the <code>paint(Graphics, JComponent)</code> method for all the UI
187   * delegates managed by this <code>MultiSplitPaneUI</code>.
188   *
189   * @param g  the graphics device.
190   * @param c  the component.
191   */
192  public void paint(Graphics g, JComponent c)
193  {
194    Iterator iterator = uis.iterator();
195    while (iterator.hasNext())
196    {
197      ComponentUI ui = (ComponentUI) iterator.next();
198      ui.paint(g, c);
199    }
200  }
201
202  /**
203   * Calls the {@link ComponentUI#getPreferredSize(JComponent)} method for all
204   * the UI delegates managed by this <code>MultiSplitPaneUI</code>,
205   * returning the preferred size for the UI delegate from the primary look and
206   * feel.
207   *
208   * @param c  the component.
209   *
210   * @return The preferred size returned by the UI delegate from the primary
211   *         look and feel.
212   */
213  public Dimension getPreferredSize(JComponent c)
214  {
215    Dimension result = null;
216    Iterator iterator = uis.iterator();
217    // first UI delegate provides the return value
218    if (iterator.hasNext())
219      {
220        ComponentUI ui = (ComponentUI) iterator.next();
221        result = ui.getPreferredSize(c);
222      }
223    // return values from auxiliary UI delegates are ignored
224    while (iterator.hasNext())
225      {
226        ComponentUI ui = (ComponentUI) iterator.next();
227        /* Dimension ignored = */ ui.getPreferredSize(c);
228      }
229    return result;
230  }
231
232  /**
233   * Calls the {@link ComponentUI#getMinimumSize(JComponent)} method for all
234   * the UI delegates managed by this <code>MultiSplitPaneUI</code>,
235   * returning the minimum size for the UI delegate from the primary look and
236   * feel.
237   *
238   * @param c  the component.
239   *
240   * @return The minimum size returned by the UI delegate from the primary
241   *         look and feel.
242   */
243  public Dimension getMinimumSize(JComponent c)
244  {
245    Dimension result = null;
246    Iterator iterator = uis.iterator();
247    // first UI delegate provides the return value
248    if (iterator.hasNext())
249      {
250        ComponentUI ui = (ComponentUI) iterator.next();
251        result = ui.getMinimumSize(c);
252      }
253    // return values from auxiliary UI delegates are ignored
254    while (iterator.hasNext())
255      {
256        ComponentUI ui = (ComponentUI) iterator.next();
257        /* Dimension ignored = */ ui.getMinimumSize(c);
258      }
259    return result;
260  }
261
262  /**
263   * Calls the {@link ComponentUI#getMaximumSize(JComponent)} method for all
264   * the UI delegates managed by this <code>MultiSplitPaneUI</code>,
265   * returning the maximum size for the UI delegate from the primary look and
266   * feel.
267   *
268   * @param c  the component.
269   *
270   * @return The maximum size returned by the UI delegate from the primary
271   *         look and feel.
272   */
273  public Dimension getMaximumSize(JComponent c)
274  {
275    Dimension result = null;
276    Iterator iterator = uis.iterator();
277    // first UI delegate provides the return value
278    if (iterator.hasNext())
279      {
280        ComponentUI ui = (ComponentUI) iterator.next();
281        result = ui.getMaximumSize(c);
282      }
283    // return values from auxiliary UI delegates are ignored
284    while (iterator.hasNext())
285      {
286        ComponentUI ui = (ComponentUI) iterator.next();
287        /* Dimension ignored = */ ui.getMaximumSize(c);
288      }
289    return result;
290  }
291
292  /**
293   * Calls the {@link ComponentUI#getAccessibleChildrenCount(JComponent)} method
294   * for all the UI delegates managed by this <code>MultiSplitPaneUI</code>,
295   * returning the count for the UI delegate from the primary look and
296   * feel.
297   *
298   * @param c  the component.
299   *
300   * @return The count returned by the UI delegate from the primary
301   *         look and feel.
302   */
303  public int getAccessibleChildrenCount(JComponent c)
304  {
305    int result = 0;
306    Iterator iterator = uis.iterator();
307    // first UI delegate provides the return value
308    if (iterator.hasNext())
309      {
310        ComponentUI ui = (ComponentUI) iterator.next();
311        result = ui.getAccessibleChildrenCount(c);
312      }
313    // return values from auxiliary UI delegates are ignored
314    while (iterator.hasNext())
315      {
316        ComponentUI ui = (ComponentUI) iterator.next();
317        /* int ignored = */ ui.getAccessibleChildrenCount(c);
318      }
319    return result;
320  }
321
322  /**
323   * Calls the {@link ComponentUI#getAccessibleChild(JComponent, int)} method
324   * for all the UI delegates managed by this <code>MultiSplitPaneUI</code>,
325   * returning the child for the UI delegate from the primary look and
326   * feel.
327   *
328   * @param c  the component
329   * @param i  the child index.
330   *
331   * @return The child returned by the UI delegate from the primary
332   *         look and feel.
333   */
334  public Accessible getAccessibleChild(JComponent c, int i)
335  {
336    Accessible result = null;
337    Iterator iterator = uis.iterator();
338    // first UI delegate provides the return value
339    if (iterator.hasNext())
340      {
341        ComponentUI ui = (ComponentUI) iterator.next();
342        result = ui.getAccessibleChild(c, i);
343      }
344    // return values from auxiliary UI delegates are ignored
345    while (iterator.hasNext())
346      {
347        ComponentUI ui = (ComponentUI) iterator.next();
348        /* Accessible ignored = */ ui.getAccessibleChild(c, i);
349      }
350    return result;
351  }
352
353  /**
354   * Calls the {@link SplitPaneUI#resetToPreferredSizes(JSplitPane)} method
355   * for all the UI delegates managed by this <code>MultiSplitPaneUI</code>.
356   *
357   * @param pane  the component.
358   */
359  public void resetToPreferredSizes(JSplitPane pane)
360  {
361    Iterator iterator = uis.iterator();
362    while (iterator.hasNext())
363    {
364      SplitPaneUI ui = (SplitPaneUI) iterator.next();
365      ui.resetToPreferredSizes(pane);
366    }
367  }
368
369  /**
370   * Calls the {@link SplitPaneUI#setDividerLocation(JSplitPane, int)} method
371   * for all the UI delegates managed by this <code>MultiSplitPaneUI</code>.
372   *
373   * @param pane  the component.
374   * @param location  the location.
375   */
376  public void setDividerLocation(JSplitPane pane, int location)
377  {
378    Iterator iterator = uis.iterator();
379    while (iterator.hasNext())
380    {
381      SplitPaneUI ui = (SplitPaneUI) iterator.next();
382      ui.setDividerLocation(pane, location);
383    }
384  }
385
386  /**
387   * Calls the {@link SplitPaneUI#getDividerLocation(JSplitPane)} method for all
388   * the UI delegates managed by this <code>MultiSplitPaneUI</code>,
389   * returning the location for the UI delegate from the primary look and
390   * feel.
391   *
392   * @param pane  the component.
393   *
394   * @return The location returned by the UI delegate from the primary
395   *         look and feel.
396   */
397  public int getDividerLocation(JSplitPane pane)
398  {
399    int result = 0;
400    Iterator iterator = uis.iterator();
401    // first UI delegate provides the return value
402    if (iterator.hasNext())
403      {
404        SplitPaneUI ui = (SplitPaneUI) iterator.next();
405        result = ui.getDividerLocation(pane);
406      }
407    // return values from auxiliary UI delegates are ignored
408    while (iterator.hasNext())
409      {
410        SplitPaneUI ui = (SplitPaneUI) iterator.next();
411        /* int ignored = */ ui.getDividerLocation(pane);
412      }
413    return result;
414  }
415
416  /**
417   * Calls the {@link SplitPaneUI#getMinimumDividerLocation(JSplitPane)} method
418   * for all the UI delegates managed by this <code>MultiSplitPaneUI</code>,
419   * returning the location for the UI delegate from the primary look and
420   * feel.
421   *
422   * @param pane  the component.
423   *
424   * @return The location returned by the UI delegate from the primary
425   *         look and feel.
426   */
427  public int getMinimumDividerLocation(JSplitPane pane)
428  {
429    int result = 0;
430    Iterator iterator = uis.iterator();
431    // first UI delegate provides the return value
432    if (iterator.hasNext())
433      {
434        SplitPaneUI ui = (SplitPaneUI) iterator.next();
435        result = ui.getMinimumDividerLocation(pane);
436      }
437    // return values from auxiliary UI delegates are ignored
438    while (iterator.hasNext())
439      {
440        SplitPaneUI ui = (SplitPaneUI) iterator.next();
441        /* int ignored = */ ui.getMinimumDividerLocation(pane);
442      }
443    return result;
444  }
445
446  /**
447   * Calls the {@link SplitPaneUI#getMaximumDividerLocation(JSplitPane)} method
448   * for all the UI delegates managed by this <code>MultiSplitPaneUI</code>,
449   * returning the location for the UI delegate from the primary look and
450   * feel.
451   *
452   * @param pane  the component.
453   *
454   * @return The location returned by the UI delegate from the primary
455   *         look and feel.
456   */
457  public int getMaximumDividerLocation(JSplitPane pane)
458  {
459    int result = 0;
460    Iterator iterator = uis.iterator();
461    // first UI delegate provides the return value
462    if (iterator.hasNext())
463      {
464        SplitPaneUI ui = (SplitPaneUI) iterator.next();
465        result = ui.getMaximumDividerLocation(pane);
466      }
467    // return values from auxiliary UI delegates are ignored
468    while (iterator.hasNext())
469      {
470        SplitPaneUI ui = (SplitPaneUI) iterator.next();
471        /* int ignored = */ ui.getMaximumDividerLocation(pane);
472      }
473    return result;
474  }
475
476  /**
477   * Calls the {@link SplitPaneUI#finishedPaintingChildren(JSplitPane,
478   * Graphics)} method for all the UI delegates managed by this
479   * <code>MultiSplitPaneUI</code>.
480   *
481   * @param pane  the component.
482   * @param g  the graphics device.
483   */
484  public void finishedPaintingChildren(JSplitPane pane, Graphics g)
485  {
486    Iterator iterator = uis.iterator();
487    while (iterator.hasNext())
488    {
489      SplitPaneUI ui = (SplitPaneUI) iterator.next();
490      ui.finishedPaintingChildren(pane, g);
491    }
492  }
493
494}