KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openide > explorer > propertysheet > CleanComboUI


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 /*
20  * CleanComboUI.java
21  *
22  * Created on 04 October 2003, 23:03
23  */

24 package org.openide.explorer.propertysheet;
25
26 import org.openide.util.Utilities;
27
28 import java.awt.*;
29 import java.awt.event.*;
30
31 import javax.swing.*;
32 import javax.swing.plaf.basic.*;
33 import javax.swing.plaf.basic.BasicComboBoxUI.ComboBoxLayoutManager;
34 import javax.swing.plaf.metal.MetalComboBoxIcon JavaDoc;
35
36
37 /** A combobox ui delegate that hides the border for use in the property
38  * sheet, and does not have problems with firing unexpected focus lost
39  * events that confuse the property sheet.
40  *
41  * @author Tim Boudreau
42  */

43 class CleanComboUI extends BasicComboBoxUI {
44     private JButton button = null;
45     private boolean tableUI;
46     private ComboPopup popup = null;
47
48     public CleanComboUI(boolean tableUI) {
49         this.tableUI = tableUI;
50     }
51
52     protected void installDefaults() {
53         LookAndFeel.installColorsAndFont(comboBox, "ComboBox.background", "ComboBox.foreground", "ComboBox.font"); //NOI18N
54

55         if (tableUI) {
56             comboBox.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0));
57         } else {
58             comboBox.setBorder(
59                 BorderFactory.createCompoundBorder(
60                     BorderFactory.createLineBorder(PropUtils.getShadowColor()),
61                     
62             //leave room for the focus rect on the left, so it doesn't
63
//overpaint the first pixel column of text
64
BorderFactory.createEmptyBorder(0, 2, 0, 0)
65                 )
66             );
67         }
68
69         installComboDefaults(comboBox);
70     }
71
72     protected ComboPopup createPopup() {
73         popup = new CleanComboPopup(comboBox);
74
75         return popup;
76     }
77
78     protected void installKeyboardActions() {
79         super.installKeyboardActions();
80
81         //Basic UI won't install an action to open the combo on spacebar,
82
//so we do it ourselves
83
if (!tableUI) {
84             comboBox.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "showPopup"); //NOI18N
85
comboBox.getActionMap().put(
86                 "showPopup",
87                 new AbstractAction() {
88                     public void actionPerformed(ActionEvent ae) {
89                         if (!comboBox.isPopupVisible()) {
90                             comboBox.showPopup();
91                         }
92                     }
93                 }
94             ); //NOI18N
95
}
96     }
97
98     protected JButton createArrowButton() {
99         Icon JavaDoc i = UIManager.getIcon("ComboBox.icon"); //NOI18N
100

101         if (i == null) {
102             i = new MetalComboBoxIcon JavaDoc();
103         }
104
105         button = new JButton(i);
106         button.setFocusable(false);
107         button.setContentAreaFilled(false);
108         button.setBorderPainted(false);
109         button.setBorder(null);
110
111         return button;
112     }
113
114     protected Insets getInsets() {
115         java.awt.Insets JavaDoc i = super.getInsets();
116         i.right += 2;
117
118         return i;
119     }
120
121     public void paint(Graphics g, JComponent c) {
122         super.paint(g, c);
123
124         if (c.hasFocus() && !tableUI) {
125             Color prev = g.getColor();
126
127             try {
128                 g.setColor(PropUtils.getShadowColor());
129                 g.drawRect(2, 2, c.getWidth() - 5, c.getHeight() - 5);
130             } finally {
131                 g.setColor(prev);
132             }
133         }
134     }
135
136     /** This focus listener is a workaround for JDK bug 4168483 -
137      * a bogus FocusLost event is sent to the combo box when the
138      * popup is shown. This results in a variety of messy behaviors.
139      * The main workaround here is to always show the popup on a
140      * focus gained event, and ignore focus lost events (they will be
141      * trapped by the property sheet if focus moves to another component,
142      * and removeEditor() will be called anyway; other focus lost events
143      * will be events in which removeEditor() will be called because the
144      * editor's action has been performed. */

145     protected FocusListener createFocusListener() {
146         return super.createFocusListener();
147
148         /*
149
150         //Code below create a focus listener without the problems associated
151         //with using standard combo boxes. We may need this in the future,
152         //so do not delete
153
154         return new FocusListener () {
155             public void focusGained( FocusEvent e ) {
156                 if (comboBox.getParent() == null) {
157                     // believe it or not, this can happen if a dialog
158                     //(such as open file server can't start) pops up
159                     //while an editor is being instantiated. Some kind
160                     //of order-of-operations problem
161                     return;
162                 }
163                 hasFocus = true;
164                 try {
165                     //Ensure the combo box has a selection. Avoid messing
166                     //with legacy editors like the form editor's - can cause
167                     //exceptions
168                     if (comboBox instanceof ComboInplaceEditor) {
169                         Object o = comboBox.getSelectedItem();
170                         if (o != null) {
171                             comboBox.getModel().setSelectedItem(o);
172                         } else {
173                             if (comboBox.getModel().getSize() >= 0) {
174                                 comboBox.setSelectedIndex(0);
175                             }
176                         }
177                         if (!comboBox.isEditable() &&
178                             //don't uatomatically show popup if custom editor button is
179                             //only visible when editing, give the user a chance to choose
180                             !PropUtils.noCustomButtons) {
181                                 if (tableUI) {
182                                     comboBox.showPopup();
183                                 } else {
184                                     comboBox.repaint();
185                                 }
186                         }
187                     }
188                 } catch (IllegalComponentStateException icse) {
189                     //Workaround for peculiar JDK bug - it tries to set focus to a
190                     //combobox that is not on screen
191                 }
192
193                 // Notify assistive technologies that the combo box
194                 // gained focus.
195                 if (comboBox instanceof Accessible) {
196                     AccessibleContext ac =
197                         ((Accessible)comboBox).getAccessibleContext();
198                     if (ac != null) {
199                         ac.firePropertyChange(
200                             AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
201                             null, AccessibleState.FOCUSED);
202                     }
203                 }
204             }
205
206             public void focusLost( FocusEvent e ) {
207                 hasFocus = false;
208                 comboBox.hidePopup();
209                 if (!tableUI) {
210                     comboBox.repaint();
211                 }
212                 if (comboBox instanceof Accessible) {
213                     AccessibleContext ac =
214                         ((Accessible)comboBox).getAccessibleContext();
215                     if (ac != null) {
216                         ac.firePropertyChange(
217                             AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
218                             AccessibleState.FOCUSED, null);
219                     }
220                 }
221             }
222         };
223          */

224     }
225
226     public void paintCurrentValue(Graphics g, Rectangle bounds, boolean hasFocus) {
227         ListCellRenderer renderer = comboBox.getRenderer();
228
229         //Fix for an obscure condition when renderer may be null -
230
//can't figure how this can happen unless the combo box is
231
//painted before installUI() has completed (which is called
232
//by the superclass constructor calling updateUI(). Only
233
//happens when opening an individual Properties window. Maybe
234
//the window is constructed off the AWT thread?
235
if ((listBox == null) || (renderer == null)) {
236             return;
237         }
238
239         Component c;
240         c = renderer.getListCellRendererComponent(listBox, comboBox.getSelectedItem(), -1, false, false);
241         c.setFont(comboBox.getFont());
242         c.setForeground(comboBox.isEnabled() ? comboBox.getForeground() : PropUtils.getDisabledForeground());
243
244         c.setBackground(comboBox.getBackground());
245
246         boolean shouldValidate = false;
247
248         if (c instanceof JPanel) {
249             shouldValidate = true;
250         }
251
252         currentValuePane.paintComponent(
253             g, c, comboBox, bounds.x, bounds.y, bounds.width, bounds.height, shouldValidate
254         );
255     }
256
257     protected Rectangle rectangleForCurrentValue() {
258         Rectangle r = super.rectangleForCurrentValue();
259
260         if (editor != null) {
261             r.x += 1;
262             r.y += 1;
263             r.width -= 1;
264             r.height -= 1;
265         }
266
267         return r;
268     }
269
270     protected ComboBoxEditor createEditor() {
271         return new CleanComboBoxEditor();
272     }
273
274     private static final void installComboDefaults(JComponent jc) {
275         Color c = UIManager.getColor("ComboBox.background"); //NOI18N
276

277         if (c == null) {
278             c = UIManager.getColor("text"); //NOI18N
279
}
280
281         if (c != null) {
282             jc.setBackground(c);
283         }
284
285         c = UIManager.getColor("ComboBox.foreground"); //NOI18N
286

287         if (c == null) {
288             c = UIManager.getColor("textText"); //NOI18N
289
}
290
291         if (c != null) {
292             jc.setForeground(c);
293         }
294
295         Font f = UIManager.getFont("ComboBox.font"); //NOI18N
296

297         if (f != null) {
298             jc.setFont(f);
299         }
300     }
301
302     private class CleanComboLayout extends ComboBoxLayoutManager {
303         public void layoutContainer(Container parent) {
304             super.layoutContainer(parent);
305
306             if (editor != null) {
307                 java.awt.Rectangle JavaDoc r = rectangleForCurrentValue();
308                 r.x = 0;
309                 r.y = 0;
310                 r.height = comboBox.getHeight();
311                 editor.setBounds(r);
312             }
313         }
314     }
315
316     private static class CleanComboPopup extends BasicComboPopup {
317         public CleanComboPopup(JComboBox box) {
318             super(box);
319             installComboDefaults(this);
320         }
321
322         protected Rectangle computePopupBounds(int px, int py, int pw, int ph) {
323             Dimension d = list.getPreferredSize();
324             Rectangle r = Utilities.getUsableScreenBounds();
325
326             if (pw < d.width) {
327                 pw = Math.min(d.width, r.width - px);
328             }
329
330             if (ph < d.height) {
331                 ph = Math.min(r.height - py, d.height);
332             }
333
334             if ((px + pw) > (r.width - px)) {
335                 px -= (r.width - pw);
336             }
337
338             Rectangle result = new Rectangle(px, py, pw, ph);
339
340             return result;
341         }
342     }
343
344     static class CleanComboBoxEditor extends BasicComboBoxEditor {
345         public CleanComboBoxEditor() {
346             editor = new JTextField();
347
348             Color c = UIManager.getColor("Table.selectionBackground"); //NOI18N
349

350             if (c == null) {
351                 c = Color.BLACK;
352             }
353
354             editor.setBorder(BorderFactory.createLineBorder(c));
355
356             // editor.setBorder (BorderFactory.createEmptyBorder());
357
}
358     }
359 }
360
Popular Tags