KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > java > swing > plaf > windows > WindowsComboBoxUI


1 /*
2  * @(#)WindowsComboBoxUI.java 1.49 07/01/09
3  *
4  * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package com.sun.java.swing.plaf.windows;
9
10 import java.beans.PropertyChangeListener JavaDoc;
11 import java.beans.PropertyChangeEvent JavaDoc;
12 import javax.swing.plaf.basic.*;
13 import javax.swing.plaf.*;
14 import javax.swing.border.*;
15 import javax.swing.*;
16 import java.awt.event.*;
17 import java.awt.*;
18
19 import com.sun.java.swing.plaf.windows.TMSchema.*;
20 import com.sun.java.swing.plaf.windows.XPStyle.Skin;
21 import sun.swing.DefaultLookup;
22
23 /**
24  * Windows combo box.
25  * <p>
26  * <strong>Warning:</strong>
27  * Serialized objects of this class will not be compatible with
28  * future Swing releases. The current serialization support is appropriate
29  * for short term storage or RMI between applications running the same
30  * version of Swing. A future release of Swing will provide support for
31  * long term persistence.
32  *
33  * @version 1.49, 01/09/07
34  * @author Tom Santos
35  * @author Igor Kushnirskiy
36  */

37
38 public class WindowsComboBoxUI extends BasicComboBoxUI {
39
40     private static final MouseListener rolloverListener =
41         new MouseAdapter() {
42             private void handleRollover(MouseEvent e, boolean isRollover) {
43                 JComboBox comboBox = getComboBox(e);
44                 WindowsComboBoxUI comboBoxUI = getWindowsComboBoxUI(e);
45                 if (comboBox == null || comboBoxUI == null) {
46                     return;
47                 }
48                 if (! comboBox.isEditable()) {
49                     //mouse over editable ComboBox does not switch rollover
50
//for the arrow button
51
ButtonModel m = null;
52                     if (comboBoxUI.arrowButton != null) {
53                         m = comboBoxUI.arrowButton.getModel();
54                     }
55                     if (m != null ) {
56                         m.setRollover(isRollover);
57                     }
58                 }
59                 comboBoxUI.isRollover = isRollover;
60                 comboBox.repaint();
61             }
62             
63             public void mouseEntered(MouseEvent e) {
64                 handleRollover(e, true);
65             }
66             
67             public void mouseExited(MouseEvent e) {
68                 handleRollover(e, false);
69             }
70             
71             private JComboBox getComboBox(MouseEvent event) {
72                 Object JavaDoc source = event.getSource();
73                 JComboBox rv = null;
74                 if (source instanceof JComboBox) {
75                     rv = (JComboBox) source;
76                 } else if (source instanceof XPComboBoxButton) {
77                     rv = ((XPComboBoxButton) source)
78                         .getWindowsComboBoxUI().comboBox;
79                 }
80                 return rv;
81             }
82             
83             private WindowsComboBoxUI getWindowsComboBoxUI(MouseEvent event) {
84                 JComboBox comboBox = getComboBox(event);
85                 WindowsComboBoxUI rv = null;
86                 if (comboBox != null
87                     && comboBox.getUI() instanceof WindowsComboBoxUI) {
88                     rv = (WindowsComboBoxUI) comboBox.getUI();
89                 }
90                 return rv;
91             }
92             
93         };
94     private boolean isRollover = false;
95
96     private static final PropertyChangeListener JavaDoc componentOrientationListener =
97         new PropertyChangeListener JavaDoc() {
98             public void propertyChange(PropertyChangeEvent JavaDoc e) {
99                 String JavaDoc propertyName = e.getPropertyName();
100                 Object JavaDoc source = null;
101                 if ("componentOrientation" == propertyName
102                     && (source = e.getSource()) instanceof JComboBox
103                     && ((JComboBox) source).getUI() instanceof
104                       WindowsComboBoxUI) {
105                     JComboBox comboBox = (JComboBox) source;
106                     WindowsComboBoxUI comboBoxUI = (WindowsComboBoxUI) comboBox.getUI();
107                     if (comboBoxUI.arrowButton instanceof XPComboBoxButton) {
108                         ((XPComboBoxButton) comboBoxUI.arrowButton).setPart(
109                                     (comboBox.getComponentOrientation() ==
110                                      ComponentOrientation.RIGHT_TO_LEFT)
111                                      ? Part.CP_DROPDOWNBUTTONLEFT
112                                      : Part.CP_DROPDOWNBUTTONRIGHT);
113                     }
114                 }
115             }
116         };
117     
118     public static ComponentUI createUI(JComponent c) {
119         return new WindowsComboBoxUI();
120     }
121
122     public void installUI( JComponent c ) {
123         super.installUI( c );
124         isRollover = false;
125         comboBox.setRequestFocusEnabled( true );
126         if (XPStyle.getXP() != null && arrowButton != null) {
127             //we can not do it in installListeners because arrowButton
128
//is initialized after installListeners is invoked
129
comboBox.addMouseListener(rolloverListener);
130             arrowButton.addMouseListener(rolloverListener);
131         }
132     }
133
134     public void uninstallUI(JComponent c) {
135         if (XPStyle.getXP() != null) {
136             comboBox.removeMouseListener(rolloverListener);
137             arrowButton.removeMouseListener(rolloverListener);
138         }
139         super.uninstallUI( c );
140     }
141     
142     @Override JavaDoc
143     protected void installListeners() {
144         super.installListeners();
145         XPStyle xp = XPStyle.getXP();
146         //button glyph for LTR and RTL combobox might differ
147
if (xp != null
148               && xp.isSkinDefined(comboBox, Part.CP_DROPDOWNBUTTONRIGHT)) {
149             comboBox.addPropertyChangeListener("componentOrientation",
150                                                componentOrientationListener);
151         }
152     }
153         
154     @Override JavaDoc
155     protected void uninstallListeners() {
156         super.uninstallListeners();
157         comboBox.removePropertyChangeListener("componentOrientation",
158                                               componentOrientationListener);
159     }
160
161     @Override JavaDoc
162     protected void configureEditor() {
163         super.configureEditor();
164         if (XPStyle.getXP() != null) {
165             editor.addMouseListener(rolloverListener);
166         }
167     }
168     
169     @Override JavaDoc
170     protected void unconfigureEditor() {
171         super.unconfigureEditor();
172         if (XPStyle.getXP() != null) {
173             editor.removeMouseListener(rolloverListener);
174         }
175     }
176
177     @Override JavaDoc
178     public void paint(Graphics g, JComponent c) {
179         if (XPStyle.getXP() != null) {
180             paintXPComboBoxBackground(g, c);
181         }
182         super.paint(g, c);
183     }
184
185     State getXPComboBoxState(JComponent c) {
186         State state = State.NORMAL;
187         if (!c.isEnabled()) {
188             state = State.DISABLED;
189         } else if (isPopupVisible(comboBox)) {
190             state = State.PRESSED;
191         } else if (isRollover) {
192             state = State.HOT;
193         }
194         return state;
195     }
196
197     private void paintXPComboBoxBackground(Graphics g, JComponent c) {
198         XPStyle xp = XPStyle.getXP();
199         State state = getXPComboBoxState(c);
200         Skin skin = null;
201         if (! comboBox.isEditable()
202               && xp.isSkinDefined(c, Part.CP_READONLY)) {
203             skin = xp.getSkin(c, Part.CP_READONLY);
204         }
205         if (skin == null) {
206             skin = xp.getSkin(c, Part.CP_COMBOBOX);
207         }
208         skin.paintSkin(g, 0, 0, c.getWidth(), c.getHeight(), state);
209     }
210
211     /**
212      * If necessary paints the currently selected item.
213      *
214      * @param g Graphics to paint to
215      * @param bounds Region to paint current value to
216      * @param hasFocus whether or not the JComboBox has focus
217      * @throws NullPointerException if any of the arguments are null.
218      * @since 1.5
219      */

220     public void paintCurrentValue(Graphics g, Rectangle bounds,
221                                   boolean hasFocus) {
222         XPStyle xp = XPStyle.getXP();
223         if (xp != null) {
224         bounds.x += 2;
225         bounds.y += 2;
226         bounds.width -= 3;
227         bounds.height -= 4;
228     } else {
229         bounds.x += 1;
230         bounds.y += 1;
231         bounds.width -= 2;
232         bounds.height -= 2;
233     }
234         if (! comboBox.isEditable()
235             && xp != null
236             && xp.isSkinDefined(comboBox, Part.CP_READONLY)) {
237             // On vista for READNLY ComboBox
238
// color for currentValue is the same as for any other item
239

240             // mostly copied from javax.swing.plaf.basic.BasicComboBoxUI.paintCurrentValue
241
ListCellRenderer renderer = comboBox.getRenderer();
242             Component c;
243             if ( hasFocus && !isPopupVisible(comboBox) ) {
244                 c = renderer.getListCellRendererComponent(
245                         listBox,
246                         comboBox.getSelectedItem(),
247                         -1,
248                         true,
249                         false );
250             } else {
251                 c = renderer.getListCellRendererComponent(
252                         listBox,
253                         comboBox.getSelectedItem(),
254                         -1,
255                         false,
256                         false );
257             }
258             c.setFont(comboBox.getFont());
259             if ( comboBox.isEnabled() ) {
260                 c.setForeground(comboBox.getForeground());
261                 c.setBackground(comboBox.getBackground());
262             } else {
263                 c.setForeground(DefaultLookup.getColor(
264                          comboBox, this, "ComboBox.disabledForeground", null));
265                 c.setBackground(DefaultLookup.getColor(
266                          comboBox, this, "ComboBox.disabledBackground", null));
267             }
268             boolean shouldValidate = false;
269             if (c instanceof JPanel) {
270                 shouldValidate = true;
271             }
272             currentValuePane.paintComponent(g, c, comboBox, bounds.x, bounds.y,
273                                    bounds.width, bounds.height, shouldValidate);
274              
275         } else {
276             super.paintCurrentValue(g, bounds, hasFocus);
277         }
278     }
279     
280     @Override JavaDoc
281     public void paintCurrentValueBackground(Graphics g, Rectangle bounds,
282                                             boolean hasFocus) {
283         if (XPStyle.getXP() == null) {
284             super.paintCurrentValueBackground(g, bounds, hasFocus);
285         }
286     }
287    
288     public Dimension getPreferredSize( JComponent c ) {
289         Dimension d = super.getPreferredSize(c);
290         d.width += 4;
291         d.height += 2;
292         if (XPStyle.getXP() != null) {
293             d.height += 2;
294         }
295         return d;
296     }
297
298     /**
299      * Creates a layout manager for managing the components which make up the
300      * combo box.
301      *
302      * @return an instance of a layout manager
303      */

304     protected LayoutManager createLayoutManager() {
305         return new BasicComboBoxUI.ComboBoxLayoutManager() {
306         public void layoutContainer(Container parent) {
307         super.layoutContainer(parent);
308
309         if (XPStyle.getXP() != null && arrowButton != null) {
310             Dimension d = parent.getSize();
311             Insets insets = getInsets();
312             int buttonWidth = arrowButton.getPreferredSize().width;
313             arrowButton.setBounds(WindowsUtils.isLeftToRight((JComboBox)parent)
314                       ? (d.width - insets.right - buttonWidth)
315                       : insets.left,
316                       insets.top,
317                       buttonWidth, d.height - insets.top - insets.bottom);
318         }
319         }
320     };
321     }
322
323     protected void installKeyboardActions() {
324         super.installKeyboardActions();
325     }
326
327     protected ComboPopup createPopup() {
328         return super.createPopup();
329     }
330
331     /**
332      * Creates the default editor that will be used in editable combo boxes.
333      * A default editor will be used only if an editor has not been
334      * explicitly set with <code>setEditor</code>.
335      *
336      * @return a <code>ComboBoxEditor</code> used for the combo box
337      * @see javax.swing.JComboBox#setEditor
338      */

339     protected ComboBoxEditor createEditor() {
340     return new WindowsComboBoxEditor();
341     }
342  
343     @Override JavaDoc
344     protected ListCellRenderer createRenderer() {
345         XPStyle xp = XPStyle.getXP();
346         if (xp != null && xp.isSkinDefined(comboBox, Part.CP_READONLY)) {
347             return new WindowsComboBoxRenderer();
348         } else {
349             return super.createRenderer();
350         }
351     }
352
353     /**
354      * Creates an button which will be used as the control to show or hide
355      * the popup portion of the combo box.
356      *
357      * @return a button which represents the popup control
358      */

359     protected JButton createArrowButton() {
360     if (XPStyle.getXP() != null) {
361         return new XPComboBoxButton();
362     } else {
363         return super.createArrowButton();
364     }
365     }
366
367     private class XPComboBoxButton extends XPStyle.GlyphButton {
368         public XPComboBoxButton() {
369             super(null,
370                   (! XPStyle.getXP().isSkinDefined(comboBox, Part.CP_DROPDOWNBUTTONRIGHT))
371                    ? Part.CP_DROPDOWNBUTTON
372                    : (comboBox.getComponentOrientation() == ComponentOrientation.RIGHT_TO_LEFT)
373                      ? Part.CP_DROPDOWNBUTTONLEFT
374                      : Part.CP_DROPDOWNBUTTONRIGHT
375                   );
376         setRequestFocusEnabled(false);
377     }
378
379         @Override JavaDoc
380         protected State getState() {
381             State rv;
382             rv = super.getState();
383             if (rv != State.DISABLED
384                 && ! comboBox.isEditable()
385                 && XPStyle.getXP().isSkinDefined(comboBox,
386                                                  Part.CP_DROPDOWNBUTTONRIGHT)) {
387                 /*
388                  * for non editable ComboBoxes Vista seems to have the
389                  * same glyph for all non DISABLED states
390                  */

391                 rv = State.NORMAL;
392             }
393             return rv;
394         }
395
396         public Dimension getPreferredSize() {
397             return new Dimension(17, 20);
398         }
399
400         void setPart(Part part) {
401             setPart(comboBox, part);
402         }
403
404         WindowsComboBoxUI getWindowsComboBoxUI() {
405             return WindowsComboBoxUI.this;
406         }
407     }
408
409     /**
410      * Subclassed to add Windows specific Key Bindings.
411      * This class is now obsolete and doesn't do anything.
412      * Only included for backwards API compatibility.
413      * Do not call or override.
414      *
415      * @deprecated As of Java 2 platform v1.4.
416      */

417     @Deprecated JavaDoc
418     protected class WindowsComboPopup extends BasicComboPopup {
419
420         public WindowsComboPopup( JComboBox cBox ) {
421             super( cBox );
422         }
423
424         protected KeyListener createKeyListener() {
425             return new InvocationKeyHandler();
426         }
427
428         protected class InvocationKeyHandler extends BasicComboPopup.InvocationKeyHandler {
429         protected InvocationKeyHandler() {
430         WindowsComboPopup.this.super();
431         }
432         }
433     }
434
435
436     /**
437      * Subclassed to highlight selected item in an editable combo box.
438      */

439     public static class WindowsComboBoxEditor
440         extends BasicComboBoxEditor.UIResource {
441
442         public void setItem(Object JavaDoc item) {
443             super.setItem(item);
444             if (editor.hasFocus()) {
445                 editor.selectAll();
446             }
447         }
448     }
449
450     /**
451      * Subclassed to set opacity {@code false} on the renderer
452      * and to show border for focused cells.
453      */

454     private static class WindowsComboBoxRenderer
455           extends BasicComboBoxRenderer.UIResource {
456         private static final Object JavaDoc BORDER_KEY = new StringBuilder JavaDoc("BORDER_KEY");
457         private static final Border NULL_BORDER = new EmptyBorder(0, 0, 0, 0);
458         /**
459          * {@inheritDoc}
460          */

461         @Override JavaDoc
462         public Component getListCellRendererComponent(
463                                                  JList list,
464                                                  Object JavaDoc value,
465                                                  int index,
466                                                  boolean isSelected,
467                                                  boolean cellHasFocus) {
468             Component rv =
469                 super.getListCellRendererComponent(list, value, index,
470                                                    isSelected, cellHasFocus);
471             if (rv instanceof JComponent) {
472                 JComponent component = (JComponent) rv;
473                 if (index == -1 && isSelected) {
474                     Border border = component.getBorder();
475                     Border dashedBorder =
476                         new WindowsBorders.DashedBorder(list.getForeground());
477                     component.setBorder(dashedBorder);
478                     //store current border in client property if needed
479
if (component.getClientProperty(BORDER_KEY) == null) {
480                         component.putClientProperty(BORDER_KEY,
481                                        (border == null) ? NULL_BORDER : border);
482                     }
483                 } else {
484                     if (component.getBorder() instanceof
485                           WindowsBorders.DashedBorder) {
486                         Object JavaDoc storedBorder = component.getClientProperty(BORDER_KEY);
487                         if (storedBorder instanceof Border) {
488                             component.setBorder(
489                                 (storedBorder == NULL_BORDER) ? null
490                                     : (Border) storedBorder);
491                         }
492                         component.putClientProperty(BORDER_KEY, null);
493                     }
494                 }
495                 if (index == -1) {
496                     component.setOpaque(false);
497                     component.setForeground(list.getForeground());
498                 } else {
499                     component.setOpaque(true);
500                 }
501             }
502             return rv;
503         }
504
505     }
506 }
507
Popular Tags