001/* MultiPanelUI.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.LookAndFeel;
048import javax.swing.UIManager;
049import javax.swing.plaf.ComponentUI;
050import javax.swing.plaf.PanelUI;
051
052/**
053 * A UI delegate that that coordinates multiple {@link PanelUI}
054 * instances, one from the primary look and feel, and one or more from the
055 * auxiliary look and feel(s).
056 *
057 * @see UIManager#addAuxiliaryLookAndFeel(LookAndFeel)
058 */
059public class MultiPanelUI extends PanelUI
060{
061
062  /** A list of references to the actual component UIs. */
063  protected Vector uis;
064
065  /**
066   * Creates a new <code>MultiPanelUI</code> instance.
067   *
068   * @see #createUI(JComponent)
069   */
070  public MultiPanelUI()
071  {
072    uis = new Vector();
073  }
074
075  /**
076   * Creates a delegate object for the specified component.  If any auxiliary
077   * look and feels support this component, a <code>MultiPanelUI</code> is
078   * returned, otherwise the UI from the default look and feel is returned.
079   *
080   * @param target  the component.
081   *
082   * @see MultiLookAndFeel#createUIs(ComponentUI, Vector, JComponent)
083   */
084  public static ComponentUI createUI(JComponent target)
085  {
086    MultiPanelUI mui = new MultiPanelUI();
087    return MultiLookAndFeel.createUIs(mui, mui.uis, target);
088  }
089
090  /**
091   * Calls the {@link ComponentUI#installUI(JComponent)} method for all
092   * the UI delegates managed by this <code>MultiPanelUI</code>.
093   *
094   * @param c  the component.
095   */
096  public void installUI(JComponent c)
097  {
098    Iterator iterator = uis.iterator();
099    while (iterator.hasNext())
100    {
101      ComponentUI ui = (ComponentUI) iterator.next();
102      ui.installUI(c);
103    }
104  }
105
106  /**
107   * Calls the {@link ComponentUI#uninstallUI(JComponent)} method for all
108   * the UI delegates managed by this <code>MultiPanelUI</code>.
109   *
110   * @param c  the component.
111   */
112  public void uninstallUI(JComponent c)
113  {
114    Iterator iterator = uis.iterator();
115    while (iterator.hasNext())
116    {
117      ComponentUI ui = (ComponentUI) iterator.next();
118      ui.uninstallUI(c);
119    }
120  }
121
122  /**
123   * Returns an array containing the UI delegates managed by this
124   * <code>MultiPanelUI</code>.  The first item in the array is always
125   * the UI delegate from the installed default look and feel.
126   *
127   * @return An array of UI delegates.
128   */
129  public ComponentUI[] getUIs()
130  {
131    return MultiLookAndFeel.uisToArray(uis);
132  }
133
134  /**
135   * Calls the {@link ComponentUI#contains(JComponent, int, int)} method for all
136   * the UI delegates managed by this <code>MultiPanelUI</code>,
137   * returning the result for the UI delegate from the primary look and
138   * feel.
139   *
140   * @param c  the component.
141   * @param x  the x-coordinate.
142   * @param y  the y-coordinate.
143   *
144   * @return <code>true</code> if the specified (x, y) coordinate falls within
145   *         the bounds of the component as rendered by the UI delegate in the
146   *         primary look and feel, and <code>false</code> otherwise.
147   */
148  public boolean contains(JComponent c, int x, int y)
149  {
150    boolean result = false;
151    Iterator iterator = uis.iterator();
152    // first UI delegate provides the return value
153    if (iterator.hasNext())
154      {
155        ComponentUI ui = (ComponentUI) iterator.next();
156        result = ui.contains(c, x, y);
157      }
158    // return values from auxiliary UI delegates are ignored
159    while (iterator.hasNext())
160      {
161        ComponentUI ui = (ComponentUI) iterator.next();
162        /* boolean ignored = */ ui.contains(c, x, y);
163      }
164    return result;
165  }
166
167  /**
168   * Calls the {@link ComponentUI#update(Graphics, JComponent)} method for all
169   * the UI delegates managed by this <code>MultiPanelUI</code>.
170   *
171   * @param g  the graphics device.
172   * @param c  the component.
173   */
174  public void update(Graphics g, JComponent c)
175  {
176    Iterator iterator = uis.iterator();
177    while (iterator.hasNext())
178    {
179      ComponentUI ui = (ComponentUI) iterator.next();
180      ui.update(g, c);
181    }
182  }
183
184  /**
185   * Calls the <code>paint(Graphics, JComponent)</code> method for all the UI
186   * delegates managed by this <code>MultiPanelUI</code>.
187   *
188   * @param g  the graphics device.
189   * @param c  the component.
190   */
191  public void paint(Graphics g, JComponent c)
192  {
193    Iterator iterator = uis.iterator();
194    while (iterator.hasNext())
195    {
196      ComponentUI ui = (ComponentUI) iterator.next();
197      ui.paint(g, c);
198    }
199  }
200
201  /**
202   * Calls the {@link ComponentUI#getPreferredSize(JComponent)} method for all
203   * the UI delegates managed by this <code>MultiPanelUI</code>,
204   * returning the preferred size for the UI delegate from the primary look and
205   * feel.
206   *
207   * @param c  the component.
208   *
209   * @return The preferred size returned by the UI delegate from the primary
210   *         look and feel.
211   */
212  public Dimension getPreferredSize(JComponent c)
213  {
214    Dimension result = null;
215    Iterator iterator = uis.iterator();
216    // first UI delegate provides the return value
217    if (iterator.hasNext())
218      {
219        ComponentUI ui = (ComponentUI) iterator.next();
220        result = ui.getPreferredSize(c);
221      }
222    // return values from auxiliary UI delegates are ignored
223    while (iterator.hasNext())
224      {
225        ComponentUI ui = (ComponentUI) iterator.next();
226        /* Dimension ignored = */ ui.getPreferredSize(c);
227      }
228    return result;
229  }
230
231  /**
232   * Calls the {@link ComponentUI#getMinimumSize(JComponent)} method for all
233   * the UI delegates managed by this <code>MultiPanelUI</code>,
234   * returning the minimum size for the UI delegate from the primary look and
235   * feel.
236   *
237   * @param c  the component.
238   *
239   * @return The minimum size returned by the UI delegate from the primary
240   *         look and feel.
241   */
242  public Dimension getMinimumSize(JComponent c)
243  {
244    Dimension result = null;
245    Iterator iterator = uis.iterator();
246    // first UI delegate provides the return value
247    if (iterator.hasNext())
248      {
249        ComponentUI ui = (ComponentUI) iterator.next();
250        result = ui.getMinimumSize(c);
251      }
252    // return values from auxiliary UI delegates are ignored
253    while (iterator.hasNext())
254      {
255        ComponentUI ui = (ComponentUI) iterator.next();
256        /* Dimension ignored = */ ui.getMinimumSize(c);
257      }
258    return result;
259  }
260
261  /**
262   * Calls the {@link ComponentUI#getMaximumSize(JComponent)} method for all
263   * the UI delegates managed by this <code>MultiPanelUI</code>,
264   * returning the maximum size for the UI delegate from the primary look and
265   * feel.
266   *
267   * @param c  the component.
268   *
269   * @return The maximum size returned by the UI delegate from the primary
270   *         look and feel.
271   */
272  public Dimension getMaximumSize(JComponent c)
273  {
274    Dimension result = null;
275    Iterator iterator = uis.iterator();
276    // first UI delegate provides the return value
277    if (iterator.hasNext())
278      {
279        ComponentUI ui = (ComponentUI) iterator.next();
280        result = ui.getMaximumSize(c);
281      }
282    // return values from auxiliary UI delegates are ignored
283    while (iterator.hasNext())
284      {
285        ComponentUI ui = (ComponentUI) iterator.next();
286        /* Dimension ignored = */ ui.getMaximumSize(c);
287      }
288    return result;
289  }
290
291  /**
292   * Calls the {@link ComponentUI#getAccessibleChildrenCount(JComponent)} method
293   * for all the UI delegates managed by this <code>MultiPanelUI</code>,
294   * returning the count for the UI delegate from the primary look and
295   * feel.
296   *
297   * @param c  the component.
298   *
299   * @return The count returned by the UI delegate from the primary
300   *         look and feel.
301   */
302  public int getAccessibleChildrenCount(JComponent c)
303  {
304    int result = 0;
305    Iterator iterator = uis.iterator();
306    // first UI delegate provides the return value
307    if (iterator.hasNext())
308      {
309        ComponentUI ui = (ComponentUI) iterator.next();
310        result = ui.getAccessibleChildrenCount(c);
311      }
312    // return values from auxiliary UI delegates are ignored
313    while (iterator.hasNext())
314      {
315        ComponentUI ui = (ComponentUI) iterator.next();
316        /* int ignored = */ ui.getAccessibleChildrenCount(c);
317      }
318    return result;
319  }
320
321  /**
322   * Calls the {@link ComponentUI#getAccessibleChild(JComponent, int)} method
323   * for all the UI delegates managed by this <code>MultiPanelUI</code>,
324   * returning the child for the UI delegate from the primary look and
325   * feel.
326   *
327   * @param c  the component
328   * @param i  the child index.
329   *
330   * @return The child returned by the UI delegate from the primary
331   *         look and feel.
332   */
333  public Accessible getAccessibleChild(JComponent c, int i)
334  {
335    Accessible result = null;
336    Iterator iterator = uis.iterator();
337    // first UI delegate provides the return value
338    if (iterator.hasNext())
339      {
340        ComponentUI ui = (ComponentUI) iterator.next();
341        result = ui.getAccessibleChild(c, i);
342      }
343    // return values from auxiliary UI delegates are ignored
344    while (iterator.hasNext())
345      {
346        ComponentUI ui = (ComponentUI) iterator.next();
347        /* Accessible ignored = */ ui.getAccessibleChild(c, i);
348      }
349    return result;
350  }
351
352}