001/* MultiLookAndFeel.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.util.Vector;
041
042import javax.swing.JComponent;
043import javax.swing.LookAndFeel;
044import javax.swing.UIDefaults;
045import javax.swing.UIManager;
046import javax.swing.plaf.ComponentUI;
047
048/**
049 * A look and feel that provides the ability to use auxiliary look and feels
050 * in addition to the primary look and feel.
051 */
052public class MultiLookAndFeel extends LookAndFeel
053{
054
055  /**
056   * Creates a new instance of the look and feel.
057   */
058  public MultiLookAndFeel()
059  {
060    // Nothing to do here.
061  }
062
063  /**
064   * Returns the name for the look and feel.
065   *
066   * @return "Multiplexing Look and Feel".
067   */
068  public String getName()
069  {
070    return "Multiplexing Look and Feel";
071  }
072
073  /**
074   * Returns an identifier for the look and feel.
075   *
076   * @return "Multiplex".
077   */
078  public String getID()
079  {
080    return "Multiplex";
081  }
082
083  /**
084   * Returns a description of the look and feel.
085   *
086   * @return A description of the look and feel.
087   */
088  public String getDescription()
089  {
090    return "Allows multiple UI instances per component instance";
091  }
092
093  /**
094   * Returns <code>false</code> to indicate that this look and feel is not
095   * native to any platform.
096   *
097   * @return <code>false</code>.
098   */
099  public boolean isNativeLookAndFeel()
100  {
101    return false;
102  }
103
104  /**
105   * Returns <code>true</code> always, since this look and feel is supported on
106   * all platforms.
107   *
108   * @return <code>true</code>.
109   */
110  public boolean isSupportedLookAndFeel()
111  {
112    return true;
113  }
114
115  /**
116   * Creates and returns the UI defaults for this look and feel.
117   *
118   * @return The UI defaults.
119   */
120  public UIDefaults getDefaults()
121  {
122    UIDefaults defaults = new UIDefaults();
123    defaults.put("ButtonUI", "javax.swing.plaf.multi.MultiButtonUI");
124    defaults.put("CheckBoxUI", "javax.swing.plaf.multi.MultiButtonUI");
125    defaults.put("CheckBoxMenuItemUI", "javax.swing.plaf.multi.MultiMenuItemUI");
126    defaults.put("ColorChooserUI",
127        "javax.swing.plaf.multi.MultiColorChooserUI");
128    defaults.put("ComboBoxUI", "javax.swing.plaf.multi.MultiComboBoxUI");
129    defaults.put("DesktopPaneUI", "javax.swing.plaf.multi.MultiDesktopPaneUI");
130    defaults.put("DesktopIconUI", "javax.swing.plaf.multi.MultiDesktopIconUI");
131    defaults.put("EditorPaneUI", "javax.swing.plaf.multi.MultiTextUI");
132    defaults.put("FileChooserUI", "javax.swing.plaf.multi.MultiFileChooserUI");
133    defaults.put("FormattedTextFieldUI", "javax.swing.plaf.multi.MultiTextUI");
134    defaults.put("InternalFrameUI",
135        "javax.swing.plaf.multi.MultiInternalFrameUI");
136    defaults.put("LabelUI", "javax.swing.plaf.multi.MultiLabelUI");
137    defaults.put("ListUI", "javax.swing.plaf.multi.MultiListUI");
138    defaults.put("MenuItemUI", "javax.swing.plaf.multi.MultiMenuItemUI");
139    defaults.put("MenuUI", "javax.swing.plaf.multi.MultiMenuItemUI");
140    defaults.put("MenuBarUI", "javax.swing.plaf.multi.MultiMenuBarUI");
141    defaults.put("OptionPaneUI", "javax.swing.plaf.multi.MultiOptionPaneUI");
142    defaults.put("PanelUI", "javax.swing.plaf.multi.MultiPanelUI");
143    defaults.put("PasswordFieldUI", "javax.swing.plaf.multi.MultiTextUI");
144    defaults.put("PopupMenuUI", "javax.swing.plaf.multi.MultiPopupMenuUI");
145    defaults.put("PopupMenuSeparatorUI",
146        "javax.swing.plaf.multi.MultiSeparatorUI");
147    defaults.put("ProgressBarUI", "javax.swing.plaf.multi.MultiProgressBarUI");
148    defaults.put("RadioButtonUI", "javax.swing.plaf.multi.MultiButtonUI");
149    defaults.put("RadioButtonMenuItemUI",
150        "javax.swing.plaf.multi.MultiMenuItemUI");
151    defaults.put("RootPaneUI", "javax.swing.plaf.multi.MultiRootPaneUI");
152    defaults.put("ScrollBarUI", "javax.swing.plaf.multi.MultiScrollBarUI");
153    defaults.put("ScrollPaneUI", "javax.swing.plaf.multi.MultiScrollPaneUI");
154    defaults.put("SeparatorUI", "javax.swing.plaf.multi.MultiSeparatorUI");
155    defaults.put("SliderUI", "javax.swing.plaf.multi.MultiSliderUI");
156    defaults.put("SpinnerUI", "javax.swing.plaf.multi.MultiSpinnerUI");
157    defaults.put("SplitPaneUI", "javax.swing.plaf.multi.MultiSplitPaneUI");
158    defaults.put("TabbedPaneUI", "javax.swing.plaf.multi.MultiTabbedPaneUI");
159    defaults.put("TableHeaderUI", "javax.swing.plaf.multi.MultiTableHeaderUI");
160    defaults.put("TableUI", "javax.swing.plaf.multi.MultiTableUI");
161    defaults.put("TextAreaUI", "javax.swing.plaf.multi.MultiTextUI");
162    defaults.put("TextFieldUI", "javax.swing.plaf.multi.MultiTextUI");
163    defaults.put("TextPaneUI", "javax.swing.plaf.multi.MultiTextUI");
164    defaults.put("ToggleButtonUI", "javax.swing.plaf.multi.MultiButtonUI");
165    defaults.put("ToolBarSeparatorUI",
166        "javax.swing.plaf.multi.MultiSeparatorUI");
167    defaults.put("ToolBarUI", "javax.swing.plaf.multi.MultiToolBarUI");
168    defaults.put("ToolTipUI", "javax.swing.plaf.multi.MultiToolTipUI");
169    defaults.put("ViewportUI", "javax.swing.plaf.multi.MultiViewportUI");
170    return defaults;
171  }
172
173  /**
174   * Creates the UI delegates for the <code>target</code> component and
175   * returns a multiplexing UI delegate (<code>mui</code>) if there are
176   * multiple delegates.
177   *
178   * @param mui  a multiplexing UI delegate appropriate for the component.
179   * @param uis  a vector into which the UI delegates will be added.
180   * @param target  the target component.
181   *
182   * @return A UI delegate.
183   */
184  public static ComponentUI createUIs(ComponentUI mui, Vector uis,
185                                      JComponent target)
186  {
187    // get primary UI delegate for 'target', and add it to uis
188    ComponentUI ui = null;
189    LookAndFeel primary = UIManager.getLookAndFeel();
190    if (primary != null)
191    {
192      ui = UIManager.getUI(target);
193      uis.add(ui);
194    }
195    // for any auxiliary look and feels in use, get the UI delegate and add
196    // it to uis
197    LookAndFeel[] auxlafs = UIManager.getAuxiliaryLookAndFeels();
198    for (int i = 0; i < auxlafs.length; i++)
199    {
200      LookAndFeel auxlaf = auxlafs[i];
201      // FIXME: here I call getDefaults() to get the UI delegate from the
202      // auxiliary look and feel.  But getDefaults() creates a new set of
203      // defaults every time it is called, which is wasteful.  Unfortunately
204      // I cannot find another way to get the UI delegate, so I'm doing it
205      // anyway...
206      UIDefaults defaults = auxlaf.getDefaults();
207      ui = defaults.getUI(target);
208      if (ui != null)
209        uis.add(ui);
210    }
211    // if uis contains more than 1 delegate, return mui, otherwise return
212    // the primary delegate
213    if (uis.size() > 1)
214      return mui;
215    else
216      return ui;
217  }
218
219  /**
220   * Returns an array containing the same {@link ComponentUI} instances as
221   * <code>uis</code>.  If <code>uis</code> is <code>null</code>, a zero-length
222   * array is returned.
223   *
224   * @param uis  a list of {@link ComponentUI} references (<code>null</code>
225   *             permitted).
226   *
227   * @return An array containing the same {@link ComponentUI} instances as
228   *         <code>uis</code>, or <code>null</code> if <code>uis</code> is
229   *         empty.
230   */
231  protected static ComponentUI[] uisToArray(Vector uis)
232  {
233    if (uis == null)
234      return new ComponentUI[0];
235    int size = uis.size();
236    if (size == 0)
237      return null;
238    ComponentUI[] result = new ComponentUI[size];
239    uis.copyInto(result);
240    return result;
241  }
242
243}