2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
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]"
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.
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.
42
* Boolean3WayEditor.java
44
* Created on April 16, 2003, 7:05 PM
46
package org.openide.explorer.propertysheet;
48
import org.openide.util.*;
50
import java.awt.Component;
51
import java.awt.Graphics;
52
import java.awt.Rectangle;
53
import java.awt.event.*;
57
import java.util.ArrayList;
58
import java.util.List;
61
import javax.swing.event.ChangeListener;
62
import javax.swing.plaf.ActionMapUIResource;
65
/** A property editor for Boolean values which can also be null to
66
* indicate the editor represents multiple conflicting values.
68
* @author Tim Boudreau
70
final class Boolean3WayEditor implements ExPropertyEditor, InplaceEditor.Factory {
73
/** Utility field holding list of PropertyChangeListeners. */
74
private transient List<PropertyChangeListener> propertyChangeListenerList;
75
private Boolean3Inplace renderer = null;
77
public Boolean3WayEditor() {
80
public String getAsText() {
82
return NbBundle.getMessage(Boolean3WayEditor.class, "CTL_Different_Values");
83
} else if (Boolean.TRUE.equals(v)) {
84
return Boolean.TRUE.toString(); //XXX use hinting
86
return Boolean.FALSE.toString(); //XXX use hinting
90
public java.awt.Component getCustomEditor() {
94
public String getJavaInitializationString() {
96
return "null"; //NOI18N
97
} else if (Boolean.TRUE.equals(v)) {
98
return "Boolean.TRUE"; //NOI18N
100
return "Boolean.FALSE"; //NOI18N
104
public String[] getTags() {
108
public Object getValue() {
112
public boolean isPaintable() {
116
public void paintValue(Graphics gfx, Rectangle box) {
117
if (renderer == null) {
118
renderer = new Boolean3Inplace();
121
renderer.setSize(box.width, box.height);
124
Graphics g = gfx.create(box.x, box.y, box.width, box.height);
125
renderer.setOpaque(false);
130
public void setAsText(String text) {
131
if (Boolean.TRUE.toString().compareToIgnoreCase(text) == 0) {
132
setValue(Boolean.TRUE);
134
setValue(Boolean.FALSE);
138
public void setValue(Object value) {
141
firePropertyChange();
145
public boolean supportsCustomEditor() {
149
public void attachEnv(PropertyEnv env) {
150
env.registerInplaceEditorFactory(this);
153
/** Registers PropertyChangeListener to receive events.
154
* @param listener The listener to register.
157
public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
158
if (propertyChangeListenerList == null) {
159
propertyChangeListenerList = new java.util.ArrayList<PropertyChangeListener>();
162
propertyChangeListenerList.add(listener);
165
/** Removes PropertyChangeListener from the list of listeners.
166
* @param listener The listener to remove.
169
public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
170
if (propertyChangeListenerList != null) {
171
propertyChangeListenerList.remove(listener);
175
/** Notifies all registered listeners about the event.
177
* @param event The event to be fired
180
private void firePropertyChange() {
183
synchronized (this) {
184
if (propertyChangeListenerList == null) {
188
list = (List) ((ArrayList) propertyChangeListenerList).clone();
191
PropertyChangeEvent event = new PropertyChangeEvent(this, null, null, null);
193
for (int i = 0; i < list.size(); i++) {
194
((PropertyChangeListener) list.get(i)).propertyChange(event);
198
/** Implementation of InplaceEditor.Factory to create an inplace editor on demand. */
199
public InplaceEditor getInplaceEditor() {
200
return new Boolean3Inplace();
203
class Boolean3Inplace extends JCheckBox implements InplaceEditor {
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;
212
setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
213
// Add a listener for when the mouse is pressed
214
super.addMouseListener(new MouseAdapter() {
217
public void mousePressed(MouseEvent e) {
219
model3way.nextState();
222
// Reset the keyboard action map
223
ActionMap map = new ActionMapUIResource();
224
map.put("pressed", new AbstractAction() {
226
public void actionPerformed(ActionEvent e) {
228
model3way.nextState();
231
map.put("released", null);
232
SwingUtilities.replaceUIActionMap(this, map);
233
// set the model to the adapted model
234
model3way = new ButtonModel3Way(getModel());
236
setState(null == v ? DONT_CARE : (v.booleanValue() ? SELECTED : NOT_SELECTED));
239
/** No one may add mouse listeners, not even Swing! */
241
public void addMouseListener(MouseListener l) {
245
* Set the new state to either SELECTED, NOT_SELECTED or
246
* DONT_CARE. If state == null, it is treated as DONT_CARE.
248
public void setState(int state) {
249
model3way.setState(state);
252
/** Return the current state, which is determined by the
253
* selection status of the model. */
254
public int getState() {
255
return model3way.getState();
259
public void setSelected(boolean b) {
263
setState(NOT_SELECTED);
268
public String getText() {
269
return PropUtils.noCheckboxCaption ? "" : NbBundle.getMessage(Boolean3WayEditor.class, "CTL_Different_Values"); //NOI18N
272
public void clear() {
273
propertyModel = null;
276
public void connect(PropertyEditor pe, PropertyEnv env) {
280
public javax.swing.JComponent getComponent() {
284
public javax.swing.KeyStroke[] getKeyStrokes() {
288
public PropertyEditor getPropertyEditor() {
289
return Boolean3WayEditor.this;
292
public Object getValue() {
293
return getState() == DONT_CARE
295
: (getState() == SELECTED ? Boolean.TRUE : Boolean.FALSE);
298
public void reset() {
301
: (v.booleanValue() ? SELECTED : NOT_SELECTED));
304
public void setValue(Object o) {
307
: (((Boolean) o).booleanValue() ? SELECTED : NOT_SELECTED));
310
public boolean supportsTextEntry() {
314
public void setPropertyModel(PropertyModel pm) {
318
public PropertyModel getPropertyModel() {
319
return propertyModel;
322
public boolean isKnownComponent(Component c) {
326
private class ButtonModel3Way implements ButtonModel {
328
private final ButtonModel other;
330
private ButtonModel3Way(ButtonModel other) {
334
private void setState(int state) {
335
if (state == NOT_SELECTED) {
336
other.setArmed(false);
339
} else if (state == SELECTED) {
340
other.setArmed(false);
344
// either "null" or DONT_CARE
345
other.setArmed(true);
352
* The current state is embedded in the selection / armed
353
* state of the model.
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.
360
private int getState() {
361
if (isSelected() && !isArmed()) {
364
} else if (isSelected() && isArmed()) {
365
// don't care grey tick
373
/** We rotate between NOT_SELECTED, SELECTED and DONT_CARE.*/
374
private void nextState() {
375
int current = getState();
376
if (current == NOT_SELECTED) {
378
} else if (current == SELECTED) {
380
} else if (current == DONT_CARE) {
381
setState(NOT_SELECTED);
385
/** Filter: No one may change the armed status except us. */
386
public void setArmed(boolean b) {
389
/** We disable focusing on the component when it is not
391
public void setEnabled(boolean b) {
396
/** All these methods simply delegate to the "other" model
397
* that is being decorated. */
398
public boolean isArmed() {
399
return other.isArmed();
402
public boolean isSelected() {
403
return other.isSelected();
406
public boolean isEnabled() {
407
return other.isEnabled();
410
public boolean isPressed() {
411
return other.isPressed();
414
public boolean isRollover() {
415
return other.isRollover();
418
public void setSelected(boolean b) {
419
other.setSelected(b);
422
public void setPressed(boolean b) {
426
public void setRollover(boolean b) {
427
other.setRollover(b);
430
public void setMnemonic(int key) {
431
other.setMnemonic(key);
434
public int getMnemonic() {
435
return other.getMnemonic();
438
public void setActionCommand(String s) {
439
other.setActionCommand(s);
442
public String getActionCommand() {
443
return other.getActionCommand();
446
public void setGroup(ButtonGroup group) {
447
other.setGroup(group);
450
public void addActionListener(ActionListener l) {
451
other.addActionListener(l);
454
public void removeActionListener(ActionListener l) {
455
other.removeActionListener(l);
458
public void addItemListener(ItemListener l) {
459
other.addItemListener(l);
462
public void removeItemListener(ItemListener l) {
463
other.removeItemListener(l);
466
public void addChangeListener(ChangeListener l) {
467
other.addChangeListener(l);
470
public void removeChangeListener(ChangeListener l) {
471
other.removeChangeListener(l);
474
public Object[] getSelectedObjects() {
475
return other.getSelectedObjects();