~ubuntu-branches/ubuntu/trusty/netbeans/trusty

« back to all changes in this revision

Viewing changes to openide/explorer/src/org/openide/explorer/propertysheet/Boolean3WayEditor.java

  • Committer: Bazaar Package Importer
  • Author(s): Marek Slama
  • Date: 2008-01-29 14:11:22 UTC
  • Revision ID: james.westby@ubuntu.com-20080129141122-fnzjbo11ntghxfu7
Tags: upstream-6.0.1
ImportĀ upstreamĀ versionĀ 6.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 
3
 *
 
4
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 
5
 *
 
6
 * The contents of this file are subject to the terms of either the GNU
 
7
 * General Public License Version 2 only ("GPL") or the Common
 
8
 * Development and Distribution License("CDDL") (collectively, the
 
9
 * "License"). You may not use this file except in compliance with the
 
10
 * License. You can obtain a copy of the License at
 
11
 * http://www.netbeans.org/cddl-gplv2.html
 
12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
 
13
 * specific language governing permissions and limitations under the
 
14
 * License.  When distributing the software, include this License Header
 
15
 * Notice in each file and include the License file at
 
16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
 
17
 * particular file as subject to the "Classpath" exception as provided
 
18
 * by Sun in the GPL Version 2 section of the License file that
 
19
 * accompanied this code. If applicable, add the following below the
 
20
 * License Header, with the fields enclosed by brackets [] replaced by
 
21
 * your own identifying information:
 
22
 * "Portions Copyrighted [year] [name of copyright owner]"
 
23
 *
 
24
 * Contributor(s):
 
25
 *
 
26
 * The Original Software is NetBeans. The Initial Developer of the Original
 
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
 
28
 * Microsystems, Inc. All Rights Reserved.
 
29
 *
 
30
 * If you wish your version of this file to be governed by only the CDDL
 
31
 * or only the GPL Version 2, indicate your decision by adding
 
32
 * "[Contributor] elects to include this software in this distribution
 
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
 
34
 * single choice of license, a recipient has the option to distribute
 
35
 * your version of this file under either the CDDL, the GPL Version 2 or
 
36
 * to extend the choice of license to its licensees as provided above.
 
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
 
38
 * Version 2 license, then the option applies only if the new code is
 
39
 * made subject to such option by the copyright holder.
 
40
 */
 
41
/*
 
42
 * Boolean3WayEditor.java
 
43
 *
 
44
 * Created on April 16, 2003, 7:05 PM
 
45
 */
 
46
package org.openide.explorer.propertysheet;
 
47
 
 
48
import org.openide.util.*;
 
49
 
 
50
import java.awt.Component;
 
51
import java.awt.Graphics;
 
52
import java.awt.Rectangle;
 
53
import java.awt.event.*;
 
54
 
 
55
import java.beans.*;
 
56
 
 
57
import java.util.ArrayList;
 
58
import java.util.List;
 
59
 
 
60
import javax.swing.*;
 
61
import javax.swing.event.ChangeListener;
 
62
import javax.swing.plaf.ActionMapUIResource;
 
63
 
 
64
 
 
65
/** A property editor for Boolean values which can also be null to
 
66
 *  indicate the editor represents multiple conflicting values.
 
67
 *
 
68
 * @author  Tim Boudreau
 
69
 */
 
70
final class Boolean3WayEditor implements ExPropertyEditor, InplaceEditor.Factory {
 
71
    Boolean v = null;
 
72
 
 
73
    /** Utility field holding list of PropertyChangeListeners. */
 
74
    private transient List<PropertyChangeListener> propertyChangeListenerList;
 
75
    private Boolean3Inplace renderer = null;
 
76
 
 
77
    public Boolean3WayEditor() {
 
78
    }
 
79
 
 
80
    public String getAsText() {
 
81
        if (v == null) {
 
82
            return NbBundle.getMessage(Boolean3WayEditor.class, "CTL_Different_Values");
 
83
        } else if (Boolean.TRUE.equals(v)) {
 
84
            return Boolean.TRUE.toString(); //XXX use hinting
 
85
        } else {
 
86
            return Boolean.FALSE.toString(); //XXX use hinting
 
87
        }
 
88
    }
 
89
 
 
90
    public java.awt.Component getCustomEditor() {
 
91
        return null;
 
92
    }
 
93
 
 
94
    public String getJavaInitializationString() {
 
95
        if (v == null) {
 
96
            return "null"; //NOI18N
 
97
        } else if (Boolean.TRUE.equals(v)) {
 
98
            return "Boolean.TRUE"; //NOI18N
 
99
        } else {
 
100
            return "Boolean.FALSE"; //NOI18N
 
101
        }
 
102
    }
 
103
 
 
104
    public String[] getTags() {
 
105
        return null;
 
106
    }
 
107
 
 
108
    public Object getValue() {
 
109
        return v;
 
110
    }
 
111
 
 
112
    public boolean isPaintable() {
 
113
        return true;
 
114
    }
 
115
 
 
116
    public void paintValue(Graphics gfx, Rectangle box) {
 
117
        if (renderer == null) {
 
118
            renderer = new Boolean3Inplace();
 
119
        }
 
120
 
 
121
        renderer.setSize(box.width, box.height);
 
122
        renderer.doLayout();
 
123
 
 
124
        Graphics g = gfx.create(box.x, box.y, box.width, box.height);
 
125
        renderer.setOpaque(false);
 
126
        renderer.paint(g);
 
127
        g.dispose();
 
128
    }
 
129
 
 
130
    public void setAsText(String text) {
 
131
        if (Boolean.TRUE.toString().compareToIgnoreCase(text) == 0) {
 
132
            setValue(Boolean.TRUE);
 
133
        } else {
 
134
            setValue(Boolean.FALSE);
 
135
        }
 
136
    }
 
137
 
 
138
    public void setValue(Object value) {
 
139
        if (v != value) {
 
140
            v = (Boolean) value;
 
141
            firePropertyChange();
 
142
        }
 
143
    }
 
144
 
 
145
    public boolean supportsCustomEditor() {
 
146
        return false;
 
147
    }
 
148
 
 
149
    public void attachEnv(PropertyEnv env) {
 
150
        env.registerInplaceEditorFactory(this);
 
151
    }
 
152
 
 
153
    /** Registers PropertyChangeListener to receive events.
 
154
     * @param listener The listener to register.
 
155
     *
 
156
     */
 
157
    public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
 
158
        if (propertyChangeListenerList == null) {
 
159
            propertyChangeListenerList = new java.util.ArrayList<PropertyChangeListener>();
 
160
        }
 
161
 
 
162
        propertyChangeListenerList.add(listener);
 
163
    }
 
164
 
 
165
    /** Removes PropertyChangeListener from the list of listeners.
 
166
     * @param listener The listener to remove.
 
167
     *
 
168
     */
 
169
    public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
 
170
        if (propertyChangeListenerList != null) {
 
171
            propertyChangeListenerList.remove(listener);
 
172
        }
 
173
    }
 
174
 
 
175
    /** Notifies all registered listeners about the event.
 
176
     *
 
177
     * @param event The event to be fired
 
178
     *
 
179
     */
 
180
    private void firePropertyChange() {
 
181
        List list;
 
182
 
 
183
        synchronized (this) {
 
184
            if (propertyChangeListenerList == null) {
 
185
                return;
 
186
            }
 
187
 
 
188
            list = (List) ((ArrayList) propertyChangeListenerList).clone();
 
189
        }
 
190
 
 
191
        PropertyChangeEvent event = new PropertyChangeEvent(this, null, null, null);
 
192
 
 
193
        for (int i = 0; i < list.size(); i++) {
 
194
            ((PropertyChangeListener) list.get(i)).propertyChange(event);
 
195
        }
 
196
    }
 
197
 
 
198
    /** Implementation of InplaceEditor.Factory to create an inplace editor on demand. */
 
199
    public InplaceEditor getInplaceEditor() {
 
200
        return new Boolean3Inplace();
 
201
    }
 
202
 
 
203
    class Boolean3Inplace extends JCheckBox implements InplaceEditor {
 
204
 
 
205
        private PropertyModel propertyModel = null;
 
206
        private final int NOT_SELECTED = 0;
 
207
        private final int SELECTED = 1;
 
208
        private final int DONT_CARE = 2;
 
209
        private final ButtonModel3Way model3way;
 
210
 
 
211
        Boolean3Inplace() {
 
212
            setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
 
213
            // Add a listener for when the mouse is pressed
 
214
            super.addMouseListener(new MouseAdapter() {
 
215
 
 
216
                @Override
 
217
                public void mousePressed(MouseEvent e) {
 
218
                    grabFocus();
 
219
                    model3way.nextState();
 
220
                }
 
221
            });
 
222
            // Reset the keyboard action map
 
223
            ActionMap map = new ActionMapUIResource();
 
224
            map.put("pressed", new AbstractAction() {
 
225
 
 
226
                public void actionPerformed(ActionEvent e) {
 
227
                    grabFocus();
 
228
                    model3way.nextState();
 
229
                }
 
230
            });
 
231
            map.put("released", null);
 
232
            SwingUtilities.replaceUIActionMap(this, map);
 
233
            // set the model to the adapted model
 
234
            model3way = new ButtonModel3Way(getModel());
 
235
            setModel(model3way);
 
236
            setState(null == v ? DONT_CARE : (v.booleanValue() ? SELECTED : NOT_SELECTED));
 
237
        }
 
238
 
 
239
        /** No one may add mouse listeners, not even Swing! */
 
240
        @Override
 
241
        public void addMouseListener(MouseListener l) {
 
242
        }
 
243
 
 
244
        /**
 
245
         * Set the new state to either SELECTED, NOT_SELECTED or
 
246
         * DONT_CARE.  If state == null, it is treated as DONT_CARE.
 
247
         */
 
248
        public void setState(int state) {
 
249
            model3way.setState(state);
 
250
        }
 
251
 
 
252
        /** Return the current state, which is determined by the
 
253
         * selection status of the model. */
 
254
        public int getState() {
 
255
            return model3way.getState();
 
256
        }
 
257
 
 
258
        @Override
 
259
        public void setSelected(boolean b) {
 
260
            if (b) {
 
261
                setState(SELECTED);
 
262
            } else {
 
263
                setState(NOT_SELECTED);
 
264
            }
 
265
        }
 
266
 
 
267
        @Override
 
268
        public String getText() {
 
269
            return PropUtils.noCheckboxCaption ? "" : NbBundle.getMessage(Boolean3WayEditor.class, "CTL_Different_Values"); //NOI18N
 
270
        }
 
271
 
 
272
        public void clear() {
 
273
            propertyModel = null;
 
274
        }
 
275
 
 
276
        public void connect(PropertyEditor pe, PropertyEnv env) {
 
277
            //do nothing
 
278
        }
 
279
 
 
280
        public javax.swing.JComponent getComponent() {
 
281
            return this;
 
282
        }
 
283
 
 
284
        public javax.swing.KeyStroke[] getKeyStrokes() {
 
285
            return null;
 
286
        }
 
287
 
 
288
        public PropertyEditor getPropertyEditor() {
 
289
            return Boolean3WayEditor.this;
 
290
        }
 
291
 
 
292
        public Object getValue() {
 
293
            return getState() == DONT_CARE 
 
294
                    ? null 
 
295
                    : (getState() == SELECTED ? Boolean.TRUE : Boolean.FALSE);
 
296
        }
 
297
 
 
298
        public void reset() {
 
299
            setState(null == v 
 
300
                    ? DONT_CARE 
 
301
                    : (v.booleanValue() ? SELECTED : NOT_SELECTED));
 
302
        }
 
303
 
 
304
        public void setValue(Object o) {
 
305
            setState(null == o 
 
306
                    ? DONT_CARE 
 
307
                    : (((Boolean) o).booleanValue() ? SELECTED : NOT_SELECTED));
 
308
        }
 
309
 
 
310
        public boolean supportsTextEntry() {
 
311
            return false;
 
312
        }
 
313
 
 
314
        public void setPropertyModel(PropertyModel pm) {
 
315
            propertyModel = pm;
 
316
        }
 
317
 
 
318
        public PropertyModel getPropertyModel() {
 
319
            return propertyModel;
 
320
        }
 
321
 
 
322
        public boolean isKnownComponent(Component c) {
 
323
            return false;
 
324
        }
 
325
 
 
326
        private class ButtonModel3Way implements ButtonModel {
 
327
 
 
328
            private final ButtonModel other;
 
329
 
 
330
            private ButtonModel3Way(ButtonModel other) {
 
331
                this.other = other;
 
332
            }
 
333
 
 
334
            private void setState(int state) {
 
335
                if (state == NOT_SELECTED) {
 
336
                    other.setArmed(false);
 
337
                    setPressed(false);
 
338
                    setSelected(false);
 
339
                } else if (state == SELECTED) {
 
340
                    other.setArmed(false);
 
341
                    setPressed(false);
 
342
                    setSelected(true);
 
343
                } else {
 
344
                    // either "null" or DONT_CARE
 
345
                    other.setArmed(true);
 
346
                    setPressed(true);
 
347
                    setSelected(true);
 
348
                }
 
349
            }
 
350
 
 
351
            /**
 
352
             * The current state is embedded in the selection / armed
 
353
             * state of the model.
 
354
             *
 
355
             * We return the SELECTED state when the checkbox is selected
 
356
             * but not armed, DONT_CARE state when the checkbox is
 
357
             * selected and armed (grey) and NOT_SELECTED when the
 
358
             * checkbox is deselected.
 
359
             */
 
360
            private int getState() {
 
361
                if (isSelected() && !isArmed()) {
 
362
                    // normal black tick
 
363
                    return SELECTED;
 
364
                } else if (isSelected() && isArmed()) {
 
365
                    // don't care grey tick
 
366
                    return DONT_CARE;
 
367
                } else {
 
368
                    // normal deselected
 
369
                    return NOT_SELECTED;
 
370
                }
 
371
            }
 
372
 
 
373
            /** We rotate between NOT_SELECTED, SELECTED and DONT_CARE.*/
 
374
            private void nextState() {
 
375
                int current = getState();
 
376
                if (current == NOT_SELECTED) {
 
377
                    setState(SELECTED);
 
378
                } else if (current == SELECTED) {
 
379
                    setState(DONT_CARE);
 
380
                } else if (current == DONT_CARE) {
 
381
                    setState(NOT_SELECTED);
 
382
                }
 
383
            }
 
384
 
 
385
            /** Filter: No one may change the armed status except us. */
 
386
            public void setArmed(boolean b) {
 
387
            }
 
388
 
 
389
            /** We disable focusing on the component when it is not
 
390
             * enabled. */
 
391
            public void setEnabled(boolean b) {
 
392
                setFocusable(b);
 
393
                other.setEnabled(b);
 
394
            }
 
395
 
 
396
            /** All these methods simply delegate to the "other" model
 
397
             * that is being decorated. */
 
398
            public boolean isArmed() {
 
399
                return other.isArmed();
 
400
            }
 
401
 
 
402
            public boolean isSelected() {
 
403
                return other.isSelected();
 
404
            }
 
405
 
 
406
            public boolean isEnabled() {
 
407
                return other.isEnabled();
 
408
            }
 
409
 
 
410
            public boolean isPressed() {
 
411
                return other.isPressed();
 
412
            }
 
413
 
 
414
            public boolean isRollover() {
 
415
                return other.isRollover();
 
416
            }
 
417
 
 
418
            public void setSelected(boolean b) {
 
419
                other.setSelected(b);
 
420
            }
 
421
 
 
422
            public void setPressed(boolean b) {
 
423
                other.setPressed(b);
 
424
            }
 
425
 
 
426
            public void setRollover(boolean b) {
 
427
                other.setRollover(b);
 
428
            }
 
429
 
 
430
            public void setMnemonic(int key) {
 
431
                other.setMnemonic(key);
 
432
            }
 
433
 
 
434
            public int getMnemonic() {
 
435
                return other.getMnemonic();
 
436
            }
 
437
 
 
438
            public void setActionCommand(String s) {
 
439
                other.setActionCommand(s);
 
440
            }
 
441
 
 
442
            public String getActionCommand() {
 
443
                return other.getActionCommand();
 
444
            }
 
445
 
 
446
            public void setGroup(ButtonGroup group) {
 
447
                other.setGroup(group);
 
448
            }
 
449
 
 
450
            public void addActionListener(ActionListener l) {
 
451
                other.addActionListener(l);
 
452
            }
 
453
 
 
454
            public void removeActionListener(ActionListener l) {
 
455
                other.removeActionListener(l);
 
456
            }
 
457
 
 
458
            public void addItemListener(ItemListener l) {
 
459
                other.addItemListener(l);
 
460
            }
 
461
 
 
462
            public void removeItemListener(ItemListener l) {
 
463
                other.removeItemListener(l);
 
464
            }
 
465
 
 
466
            public void addChangeListener(ChangeListener l) {
 
467
                other.addChangeListener(l);
 
468
            }
 
469
 
 
470
            public void removeChangeListener(ChangeListener l) {
 
471
                other.removeChangeListener(l);
 
472
            }
 
473
 
 
474
            public Object[] getSelectedObjects() {
 
475
                return other.getSelectedObjects();
 
476
            }
 
477
        }
 
478
    }
 
479
}