KickJava   Java API By Example, From Geeks To Geeks.

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


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 * RadioInplaceEditor.java
21 *
22 * Created on 28 September 2003, 01:41
23 */

24 package org.openide.explorer.propertysheet;
25
26 import org.openide.util.WeakSet;
27
28 import java.awt.Color JavaDoc;
29 import java.awt.Component JavaDoc;
30 import java.awt.Dimension JavaDoc;
31 import java.awt.FontMetrics JavaDoc;
32 import java.awt.Graphics JavaDoc;
33 import java.awt.Insets JavaDoc;
34 import java.awt.Point JavaDoc;
35 import java.awt.Rectangle JavaDoc;
36 import java.awt.event.ActionEvent JavaDoc;
37 import java.awt.event.ActionListener JavaDoc;
38 import java.awt.event.InputEvent JavaDoc;
39 import java.awt.event.MouseEvent JavaDoc;
40
41 import java.beans.PropertyEditor JavaDoc;
42
43 import java.util.ArrayList JavaDoc;
44 import java.util.Iterator JavaDoc;
45 import java.util.List JavaDoc;
46
47 import javax.swing.ButtonGroup JavaDoc;
48 import javax.swing.JComponent JavaDoc;
49 import javax.swing.JPanel JavaDoc;
50 import javax.swing.JRadioButton JavaDoc;
51 import javax.swing.KeyStroke JavaDoc;
52 import javax.swing.SwingUtilities JavaDoc;
53 import javax.swing.border.TitledBorder JavaDoc;
54
55
56 /** An inplace editor that represents the contents of a property editor's
57  * getTags() method as a set of radio buttons. For larger sets of choices
58  * it is preferable to use a combo box, but for situations where only 3 to 5
59  * options are available, this is preferable.
60  *
61  * @author Tim Boudreau
62  */

63 class RadioInplaceEditor extends JPanel JavaDoc implements InplaceEditor, ActionListener JavaDoc {
64     private transient List JavaDoc<ActionListener JavaDoc> actionListenerList;
65     protected transient PropertyEditor JavaDoc editor = null;
66     protected transient PropertyEnv env = null;
67     protected transient PropertyModel mdl = null;
68     protected transient ButtonGroup JavaDoc group = null;
69     private boolean tableUI = false;
70     boolean isFirstEvent = false;
71     private WeakSet<InvRadioButton> buttonCache = new WeakSet<InvRadioButton>();
72     private boolean useTitle = false;
73
74     public RadioInplaceEditor(boolean tableUI) {
75         setLayout(new AutoGridLayout(false));
76         this.tableUI = tableUI;
77         setOpaque(true);
78     }
79
80     public void clear() {
81         editor = null;
82         env = null;
83         mdl = null;
84         group = null;
85
86         Component JavaDoc[] c = getComponents();
87
88         for (int i = 0; i < c.length; i++) {
89             if (c[i] instanceof JRadioButton JavaDoc) {
90                 ((JRadioButton JavaDoc) c[i]).removeActionListener(this);
91             }
92         }
93
94         removeAll();
95         setEnabled(true);
96     }
97
98     /** Overridden to avoid grabbing the AWT tree lock */
99     public Dimension JavaDoc getPreferredSize() {
100         if (getLayout() != null) {
101             return getLayout().preferredLayoutSize(this);
102         } else {
103             return super.getPreferredSize();
104         }
105     }
106
107     public void addNotify() {
108         super.addNotify();
109         isFirstEvent = true;
110     }
111
112     private InvRadioButton[] getButtons(int count) {
113         InvRadioButton[] result = new InvRadioButton[count];
114
115         Iterator JavaDoc<InvRadioButton> i = buttonCache.iterator();
116         int idx = 0;
117
118         while (i.hasNext() && (idx < count)) {
119             result[idx] = i.next();
120
121             if (result[idx] != null) {
122                 result[idx].setEnabled(true);
123                 result[idx].setSelected(false);
124                 idx++;
125             }
126         }
127
128         for (; idx < count; idx++) {
129             result[idx] = createButton();
130             buttonCache.add(result[idx]);
131         }
132
133         return result;
134     }
135
136     public void setEnabled(boolean val) {
137         // System.err.println("RadioEditor.setEnabled " + val);
138
super.setEnabled(val);
139
140         Component JavaDoc[] c = getComponents();
141
142         for (int i = 0; i < c.length; i++) {
143             c[i].setEnabled(val);
144         }
145     }
146
147     public void setBackground(Color JavaDoc col) {
148         super.setBackground(col);
149
150         Component JavaDoc[] c = getComponents();
151
152         for (int i = 0; i < c.length; i++) {
153             c[i].setBackground(col);
154         }
155     }
156
157     public void setForeground(Color JavaDoc col) {
158         super.setForeground(col);
159
160         Component JavaDoc[] c = getComponents();
161
162         for (int i = 0; i < c.length; i++) {
163             c[i].setForeground(col);
164         }
165     }
166
167     /** In 1.4, panels can and will receive focus; if we define our own
168      * focus policy, we're responsible for all possible subcomponents.
169      * Therfore just proxy requestFocusInWindow for the selected radio
170      * button */

171     public void requestFocus() {
172         Component JavaDoc[] c = getComponents();
173
174         if (c.length > 0) {
175             for (int i = 0; i < c.length; i++) {
176                 if (c[i] instanceof InvRadioButton && ((InvRadioButton) c[i]).isSelected()) {
177                     c[i].requestFocus();
178
179                     return;
180                 }
181             }
182
183             c[0].requestFocus();
184         } else {
185             super.requestFocus();
186         }
187     }
188
189     public boolean requestFocusInWindow() {
190         Component JavaDoc[] c = getComponents();
191
192         for (int i = 0; i < c.length; i++) {
193             if (c[i] instanceof InvRadioButton && ((InvRadioButton) c[i]).isSelected()) {
194                 return c[i].requestFocusInWindow();
195             }
196         }
197
198         return super.requestFocusInWindow();
199     }
200
201     public void setUseTitle(boolean val) {
202         if (useTitle != val) {
203             useTitle = val;
204
205             if (env != null) {
206                 setBorder(new TitledBorder JavaDoc(env.getFeatureDescriptor().getDisplayName()));
207             }
208         }
209     }
210
211     public void connect(PropertyEditor JavaDoc pe, PropertyEnv env) {
212         if (!tableUI && (env != null) && useTitle) {
213             setBorder(new TitledBorder JavaDoc(env.getFeatureDescriptor().getDisplayName()));
214         } else {
215             setBorder(null);
216         }
217
218         editor = pe;
219
220         String JavaDoc[] tags = editor.getTags();
221         group = new ButtonGroup JavaDoc();
222
223         InvRadioButton[] buttons = getButtons(tags.length);
224
225         if (env != null) {
226             setEnabled(env.isEditable());
227         }
228
229         for (int i = 0; i < tags.length; i++) {
230             InvRadioButton jr = buttons[i];
231             configureButton(jr, tags[i]);
232             add(jr);
233         }
234     }
235
236     /** Renderer version overrides this to create a subclass that won't
237      * fire changes */

238     protected InvRadioButton createButton() {
239         return new InvRadioButton();
240     }
241
242     /** Renderer version overrides this */
243     protected void configureButton(InvRadioButton ire, String JavaDoc txt) {
244         ire.addActionListener(this);
245
246         if (editor.getTags().length == 1) {
247             ire.setEnabled(false);
248         } else {
249             ire.setEnabled(isEnabled());
250         }
251
252         if (tableUI) {
253             ire.setFocusable(false);
254         } else {
255             ire.setFocusable(true);
256         }
257
258         ire.setText(txt);
259
260         if (txt.equals(editor.getAsText())) {
261             ire.setSelected(true);
262         } else {
263             ire.setSelected(false);
264         }
265
266         ire.setFont(getFont());
267         ire.setBackground(getBackground());
268         ire.setForeground(getForeground());
269         group.add(ire);
270     }
271
272     public JComponent JavaDoc getComponent() {
273         return this;
274     }
275
276     public KeyStroke JavaDoc[] getKeyStrokes() {
277         return null;
278     }
279
280     public PropertyEditor JavaDoc getPropertyEditor() {
281         return editor;
282     }
283
284     public PropertyModel getPropertyModel() {
285         return mdl;
286     }
287
288     public Object JavaDoc getValue() {
289         Component JavaDoc[] c = getComponents();
290
291         // System.out.println("GetSelection is " + group.getSelection());
292
for (int i = 0; i < c.length; i++) {
293             if (c[i] instanceof JRadioButton JavaDoc) {
294                 if (group.getSelection() == ((JRadioButton JavaDoc) c[i]).getModel()) {
295                     String JavaDoc result = ((JRadioButton JavaDoc) c[i]).getText();
296
297                     return result;
298                 }
299             }
300         }
301
302         return null;
303     }
304
305     public void handleInitialInputEvent(InputEvent JavaDoc e) {
306         System.err.println("HandleInitialInputEvent");
307         getLayout().layoutContainer(this);
308
309         if (e instanceof MouseEvent JavaDoc) {
310             Point JavaDoc p = SwingUtilities.convertPoint((JComponent JavaDoc) e.getSource(), ((MouseEvent JavaDoc) e).getPoint(), this);
311             Component JavaDoc c = getComponentAt(p);
312
313             if (c instanceof JRadioButton JavaDoc) {
314                 ((JRadioButton JavaDoc) c).setSelected(true);
315                 c.requestFocus();
316                 fireActionPerformed(new ActionEvent JavaDoc(this, ActionEvent.ACTION_PERFORMED, InplaceEditor.COMMAND_SUCCESS));
317             }
318         } else {
319             Component JavaDoc[] c = getComponents();
320
321             for (int i = 0; i < c.length; i++) {
322                 if (c[i] instanceof JRadioButton JavaDoc) {
323                     if (((JRadioButton JavaDoc) c[i]).isSelected()) {
324                         c[i].requestFocusInWindow();
325                     }
326                 }
327             }
328         }
329     }
330
331     public boolean isKnownComponent(Component JavaDoc c) {
332         return (c != null) && ((c == this) || c instanceof InvRadioButton);
333     }
334
335     public void reset() {
336         setValue(editor.getAsText());
337     }
338
339     public void setPropertyModel(PropertyModel pm) {
340         mdl = pm;
341     }
342
343     public void setValue(Object JavaDoc o) {
344         Component JavaDoc[] c = getComponents();
345
346         for (int i = 0; i < c.length; i++) {
347             if (c[i] instanceof JRadioButton JavaDoc) {
348                 if (((JRadioButton JavaDoc) c[i]).getText().equals(o)) {
349                     ((JRadioButton JavaDoc) c[i]).setSelected(true);
350                 } else {
351                     //Necessary for renderer, its buttons don't fire changes
352
((JRadioButton JavaDoc) c[i]).setSelected(false);
353                 }
354             }
355         }
356     }
357
358     public boolean supportsTextEntry() {
359         return false;
360     }
361
362     public synchronized void addActionListener(java.awt.event.ActionListener JavaDoc listener) {
363         if (actionListenerList == null) {
364             actionListenerList = new java.util.ArrayList JavaDoc<ActionListener JavaDoc>();
365         }
366
367         actionListenerList.add(listener);
368     }
369
370     public synchronized void removeActionListener(java.awt.event.ActionListener JavaDoc listener) {
371         if (actionListenerList != null) {
372             actionListenerList.remove(listener);
373         }
374     }
375
376     private void fireActionPerformed(final java.awt.event.ActionEvent JavaDoc event) {
377         // System.err.println("Radio editor firing action performed " + event.getActionCommand());
378
java.util.List JavaDoc list;
379
380         synchronized (this) {
381             if (actionListenerList == null) {
382                 return;
383             }
384
385             list = (List JavaDoc) ((ArrayList JavaDoc) actionListenerList).clone();
386         }
387
388         final java.util.List JavaDoc theList = list;
389
390         //When used in a table, the typical case is that the editor is instantiated,
391
//processes its mouse event, fires an event and is immediately removed.
392
//Using invokeLater allows the table to repaint appropriately for selection,
393
//etc, reducing flicker.
394
if (tableUI) {
395             SwingUtilities.invokeLater(
396                 new Runnable JavaDoc() {
397                     public void run() {
398                         for (int i = 0; i < theList.size(); i++) {
399                             ((java.awt.event.ActionListener JavaDoc) theList.get(i)).actionPerformed(event);
400                         }
401                     }
402                 }
403             );
404         } else {
405             for (int i = 0; i < list.size(); i++) {
406                 ((java.awt.event.ActionListener JavaDoc) theList.get(i)).actionPerformed(event);
407             }
408         }
409     }
410
411     public void actionPerformed(ActionEvent JavaDoc e) {
412         ActionEvent JavaDoc ae = new ActionEvent JavaDoc(this, ActionEvent.ACTION_PERFORMED, InplaceEditor.COMMAND_SUCCESS);
413         fireActionPerformed(ae);
414     }
415
416     public void paint(Graphics JavaDoc g) {
417         if (isShowing()) {
418             super.paint(g);
419         } else {
420             getLayout().layoutContainer(this);
421
422             Component JavaDoc[] c = getComponents();
423             Color JavaDoc col = g.getColor();
424
425             try {
426                 g.setColor(getBackground());
427                 g.fillRect(0, 0, getWidth(), getHeight());
428
429                 for (int i = 0; i < c.length; i++) {
430                     Rectangle JavaDoc r = c[i].getBounds();
431
432                     if (g.hitClip(r.x, r.y, r.width, r.height)) {
433                         Graphics JavaDoc g2 = g.create(r.x, r.y, r.width, r.height);
434
435                         try {
436                             c[i].paint(g2);
437                         } finally {
438                             g2.dispose();
439                         }
440                     }
441                 }
442
443                 if (getBorder() != null) {
444                     super.paintBorder(g);
445                 }
446             } finally {
447                 g.setColor(col);
448             }
449         }
450     }
451
452     public void processMouseEvent(MouseEvent JavaDoc me) {
453         if (isFirstEvent) {
454             handleInitialInputEvent(me);
455             isFirstEvent = false;
456         } else {
457             super.processMouseEvent(me);
458         }
459     }
460
461     public Component JavaDoc getComponentAt(int x, int y) {
462         getLayout().layoutContainer(this);
463
464         Component JavaDoc result = super.getComponentAt(x, y);
465         System.err.println("getComponentAt " + x + "," + y + " returning " + result.getName());
466
467         return result;
468     }
469
470     /** A JRadioButton that can calculate its preferred size when it
471      * has no parent */

472     class InvRadioButton extends JRadioButton JavaDoc {
473         public InvRadioButton() {
474             super();
475         }
476
477         public String JavaDoc getName() {
478             return "InvRadioButton - " + getText(); //NOI18N
479
}
480
481         public void processKeyEvent(java.awt.event.KeyEvent JavaDoc ke) {
482             super.processKeyEvent(ke);
483
484             if (
485                 ((ke.getKeyCode() == ke.VK_ENTER) || (ke.getKeyCode() == ke.VK_ESCAPE)) &&
486                     (ke.getID() == ke.KEY_PRESSED)
487             ) {
488                 RadioInplaceEditor.this.fireActionPerformed(
489                     new ActionEvent JavaDoc(
490                         this, ActionEvent.ACTION_PERFORMED,
491                         (ke.getKeyCode() == ke.VK_ENTER) ? COMMAND_SUCCESS : COMMAND_FAILURE
492                     )
493                 );
494             }
495         }
496
497         public Dimension JavaDoc getPreferredSize() {
498             int w = 0;
499             int h = 0;
500             Graphics JavaDoc g = PropUtils.getScratchGraphics(this);
501             FontMetrics JavaDoc fm = g.getFontMetrics(getFont());
502
503             if (getIcon() != null) {
504                 w = getIcon().getIconWidth();
505                 h = getIcon().getIconHeight();
506             }
507
508             if (getBorder() != null) {
509                 Insets JavaDoc ins = getBorder().getBorderInsets(this);
510                 w += (ins.left + ins.right);
511                 h += (ins.bottom + ins.top);
512             }
513
514             w += (fm.stringWidth(getText()) + 22);
515             h = Math.max(fm.getHeight(), h) + 2;
516
517             return new Dimension JavaDoc(w, h);
518         }
519     }
520 }
521
Popular Tags