1 /* MetalComboBoxUI.java
2    Copyright (C) 2005 Free Software Foundation, Inc.
3 
4 This file is part of GNU Classpath.
5 
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20 
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25 
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37 
38 
39 package javax.swing.plaf.metal;
40 
41 import java.awt.Container;
42 import java.awt.Dimension;
43 import java.awt.Graphics;
44 import java.awt.Insets;
45 import java.awt.LayoutManager;
46 import java.awt.Rectangle;
47 import java.awt.event.MouseEvent;
48 import java.beans.PropertyChangeEvent;
49 import java.beans.PropertyChangeListener;
50 
51 import javax.swing.CellRendererPane;
52 import javax.swing.ComboBoxEditor;
53 import javax.swing.Icon;
54 import javax.swing.JButton;
55 import javax.swing.JComboBox;
56 import javax.swing.JComponent;
57 import javax.swing.plaf.ComponentUI;
58 import javax.swing.plaf.basic.BasicComboBoxUI;
59 import javax.swing.plaf.basic.BasicComboPopup;
60 import javax.swing.plaf.basic.ComboPopup;
61 
62 
63 /**
64  * A UI delegate for the {@link JComboBox} component.
65  */
66 public class MetalComboBoxUI extends BasicComboBoxUI
67 {
68   /**
69    * A layout manager that arranges the editor component (if active) and the
70    * button that make up the combo box.
71    */
72   public class MetalComboBoxLayoutManager
73     extends BasicComboBoxUI.ComboBoxLayoutManager
74   {
75     /**
76      * Creates a new instance of the layout manager.
77      */
MetalComboBoxLayoutManager()78     public MetalComboBoxLayoutManager()
79     {
80       // Nothing to do here.
81     }
82 
83     /**
84      * Arranges the editor (if visible) and button that comprise the combo
85      * box.
86      *
87      * @param parent  the parent.
88      */
layoutContainer(Container parent)89     public void layoutContainer(Container parent)
90     {
91       JComboBox cb = (JComboBox) parent;
92       if (!cb.isEditable())
93         {
94           Rectangle bounds = parent.getBounds();
95           arrowButton.setBounds(0, 0, bounds.width, bounds.height);
96         }
97       else
98         superLayout(parent);
99     }
100 
101     /**
102      * Calls the <code>layoutContainer(Container)</code> method in the super
103      * class.
104      *
105      * @param parent  the container.
106      */
superLayout(Container parent)107     public void superLayout(Container parent)
108     {
109       super.layoutContainer(parent);
110     }
111   }
112 
113   /**
114    * A listener used to handle property changes in the {@link JComboBox}
115    * component, to ensure that the UI delegate accurately reflects the current
116    * state in the rendering onscreen.
117    */
118   public class MetalPropertyChangeListener
119     extends BasicComboBoxUI.PropertyChangeHandler
120   {
121     /**
122      * Creates a new listener.
123      */
MetalPropertyChangeListener()124     public MetalPropertyChangeListener()
125     {
126       // Nothing to do here.
127     }
128 
129     /**
130      * Handles a property change event, updating the UI components as
131      * appropriate.
132      *
133      * @param e  the event.
134      */
propertyChange(PropertyChangeEvent e)135     public void propertyChange(PropertyChangeEvent e)
136     {
137       if (e.getPropertyName().equals("editable"))
138         editablePropertyChanged(e);
139       super.propertyChange(e);
140     }
141   }
142 
143   /**
144    * A popup menu for the combo-box.
145    *
146    * @see #createPopup()
147    *
148    * @deprecated 1.4
149    */
150   public class MetalComboPopup extends BasicComboPopup
151   {
152     /**
153      * Creates a new popup.
154      *
155      * @param cBox  the combo box.
156      */
MetalComboPopup(JComboBox cBox)157     public MetalComboPopup(JComboBox cBox)
158     {
159       super(cBox);
160     }
161 
delegateFocus(MouseEvent e)162     public void delegateFocus(MouseEvent e)
163     {
164       super.delegateFocus(e);
165     }
166   }
167 
168   /**
169    * Constructs a new instance of MetalComboBoxUI.
170    */
MetalComboBoxUI()171   public MetalComboBoxUI()
172   {
173     super();
174   }
175 
176   /**
177    * Returns an instance of MetalComboBoxUI.
178    *
179    * @param component the component for which we return an UI instance
180    *
181    * @return an instance of MetalComboBoxUI
182    */
createUI(JComponent component)183   public static ComponentUI createUI(JComponent component)
184   {
185     return new MetalComboBoxUI();
186   }
187 
188   /**
189    * Creates an editor for the combo box.
190    *
191    * @return An editor.
192    */
createEditor()193   protected ComboBoxEditor createEditor()
194   {
195     return new MetalComboBoxEditor.UIResource();
196   }
197 
198   /**
199    * Creates a popup for the combo box.
200    *
201    * @return A popup.
202    */
createPopup()203   protected ComboPopup createPopup()
204   {
205     return new MetalComboPopup(comboBox);
206   }
207 
208   /**
209    * Creates a new button for use in rendering the JComboBox.
210    *
211    * @return A button.
212    */
createArrowButton()213   protected JButton createArrowButton()
214   {
215     JButton button = new MetalComboBoxButton(comboBox, new MetalComboBoxIcon(),
216             new CellRendererPane(), listBox);
217     button.setMargin(new Insets(0, 1, 1, 3));
218     return button;
219   }
220 
221   /**
222    * Creates a new property change listener.
223    *
224    * @return A new property change listener.
225    */
createPropertyChangeListener()226   public PropertyChangeListener createPropertyChangeListener()
227   {
228     return new MetalPropertyChangeListener();
229   }
230 
paint(Graphics g, JComponent c)231   public void paint(Graphics g, JComponent c)
232   {
233     // do nothing, the button and text field are painted elsewhere
234   }
235 
236   /**
237    * Updates the button and text field to reflect a change in the 'editable'
238    * property.
239    *
240    * @param e  the event.
241    *
242    * @deprecated 1.4
243    */
editablePropertyChanged(PropertyChangeEvent e)244   protected void editablePropertyChanged(PropertyChangeEvent e)
245   {
246     if (arrowButton instanceof MetalComboBoxButton)
247       {
248         MetalComboBoxButton b = (MetalComboBoxButton) arrowButton;
249         b.setIconOnly(comboBox.isEditable());
250       }
251     if (comboBox.isEditable())
252       {
253         arrowButton.setText(null);
254         if (editor != null)
255           editor.setVisible(true);
256       }
257     else
258       {
259         String text = "";
260         Object selected = comboBox.getSelectedItem();
261         if (selected != null)
262           text = selected.toString();
263         arrowButton.setText(text);
264         if (editor != null)
265           editor.setVisible(true);
266       }
267   }
268 
269   /**
270    * Creates a new layout manager for the UI delegate.
271    *
272    * @return A new layout manager.
273    */
createLayoutManager()274   protected LayoutManager createLayoutManager()
275   {
276     return new MetalComboBoxLayoutManager();
277   }
278 
279   /**
280    * Not used in Classpath.
281    *
282    * @deprecated 1.4
283    */
removeListeners()284   protected void removeListeners()
285   {
286     // no longer used in JDK 1.4
287   }
288 
289   /**
290    * Returns the minimum size for the combo.
291    *
292    * @param c  the component
293    *
294    * @return The minimum size for the combo box.
295    */
getMinimumSize(JComponent c)296   public Dimension getMinimumSize(JComponent c)
297   {
298     MetalComboBoxButton b = (MetalComboBoxButton) arrowButton;
299     Icon icon = b.getComboIcon();
300     Insets insets = b.getInsets();
301     Dimension d = getDisplaySize();
302     int insetsH = insets.top + insets.bottom;
303     int insetsW = insets.left + insets.right;
304     int iconWidth = icon.getIconWidth() + 6;
305     return new Dimension(d.width + insetsW + iconWidth,
306             d.height + insetsH);
307   }
308 
309 }
310