package cern.gp.beans.editors; import java.awt.Color; import java.awt.Component; import java.beans.FeatureDescriptor; import java.beans.PropertyEditorSupport; import java.lang.reflect.InvocationTargetException; import javax.swing.JCheckBox; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.openide.explorer.propertysheet.ExPropertyEditor; import org.openide.explorer.propertysheet.PropertyEnv; import org.openide.explorer.propertysheet.editors.EnhancedPropertyEditor; import org.openide.nodes.Node; import org.openide.nodes.Node.Property; /** * An editor to place a JCheckBox into a cell of an Explorer. This is to be asociated * with a boolean property. * * @author Vito Baggiolini * * @version $Revision: 1.2 $, $Date: 2006/09/25 08:52:36 $, $Author: acaproni $ */ public class CheckBoxEditor extends PropertyEditorSupport implements EnhancedPropertyEditor, ExPropertyEditor { private boolean editableMode; private PropertyEnv propertyEnv; private final JCheckBox renderer; private JCheckBox editor; /** * default constructor, opens the Editor already in Editable mode, i.e. the first * click on the editor changes the value already */ public CheckBoxEditor() { this(true); } /** * @param eitableMode if true, the editor is active on the first click, if not, * the user has to click first to be able to change the checkbox. */ public CheckBoxEditor(boolean editableMode) { //TODO see if this can be done with PropertyPanel.PREF_INPUT_STATE this.editableMode = editableMode; renderer = new JCheckBox(); renderer.setOpaque(false); } /* * (non-Javadoc) * @see java.beans.PropertyEditor#isPaintable() */ public boolean isPaintable() { return true; } /* * (non-Javadoc) * @see java.beans.PropertyEditor#paintValue(java.awt.Graphics, java.awt.Rectangle) */ public void paintValue(java.awt.Graphics gfx, java.awt.Rectangle box) { gfx.translate(box.x, box.y); boolean b = getBoolValue(); renderer.setSelected(b); renderer.setSize(box.width, box.height); renderer.paint(gfx); gfx.translate(-box.x, -box.y); } /* * (non-Javadoc) * @see org.openide.explorer.propertysheet.editors.EnhancedPropertyEditor#getInPlaceCustomEditor() */ public Component getInPlaceCustomEditor() { if (editor == null) { editor = new JCheckBox(); editor.setOpaque(false); editor.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { setBoolValue(editor.isSelected()); } }); } if (!editableMode) { editor.setSelected(getBoolValue()); } else { // immediately invert the selection. This is what the user expects, because he does not want to click twice on the // checkbox. We want to avoid the normal behavior of the program, that requires you to click once to activate // editing mode and once to change the value. boolean invBoolValue = !getBoolValue(); editor.setSelected(invBoolValue); Boolean invBooleanObject = invBoolValue ? Boolean.TRUE : Boolean.FALSE; // we have to go directly to the Node.Property because this object (the PropertyEditor) // does not propagate a setValue(invBoolValue). It gets blocked in the propertyChange() method of // the private class PropertyPanel.EditorListener. // this is less of a Hack than it looks like, c.f. Javadoc of // {@link org.openide.explorer.propertysheet.PropertyEnv.getFeatureDescriptor()} FeatureDescriptor fd = propertyEnv.getFeatureDescriptor(); if (fd instanceof Node.Property) { try { setNodeProperty(invBoolValue, (Property) fd); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { System.out.println("fd not Node.Property, but " + fd.getClass()); } // nevertheless call this.setValue() to be coherent setBoolValue(invBoolValue); } return editor; } protected void setNodeProperty(boolean newValue, Node.Property fd) throws IllegalAccessException, InvocationTargetException { fd.setValue(newValue ? Boolean.TRUE : Boolean.FALSE); } /* * (non-Javadoc) * @see org.openide.explorer.propertysheet.editors.EnhancedPropertyEditor#hasInPlaceCustomEditor() */ public boolean hasInPlaceCustomEditor() { return true; } /* * (non-Javadoc) * @see org.openide.explorer.propertysheet.editors.EnhancedPropertyEditor#supportsEditingTaggedValues() */ public boolean supportsEditingTaggedValues() { return false; } /** * Returns value of the property as boolean * * @return value of the property */ protected boolean getBoolValue() { return ((Boolean) getValue()).booleanValue(); } protected void setBoolValue(boolean newValue) { setValue(newValue? Boolean.TRUE : Boolean.FALSE); } /* (non-Javadoc) * @see org.openide.explorer.propertysheet.ExPropertyEditor#attachEnv(org.openide.explorer.propertysheet.PropertyEnv) */ public void attachEnv(PropertyEnv env) { propertyEnv = env; } public void setBackground(Color color) { if (color != null) { renderer.setOpaque(true); renderer.setBackground(color); } else { renderer.setOpaque(false); } } }