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