UndoRedo on Nodes
Posted
by Geertjan
on Oracle Blogs
See other posts from Oracle Blogs
or by Geertjan
Published on Wed, 23 Nov 2011 02:51:17 -0600
Indexed on
2011/11/24
10:13 UTC
Read the original article
Hit count: 466
/NetBeans IDE
When a change is made to the property in the Properties Window, below, the undo/redo functionality becomes enabled:
When undo/redo are invoked, e.g., via the buttons in the toolbar, the display name of the node changes accordingly. The only problem I have is that the buttons only become enabled when the Person Window is selected, not when the Properties Window is selected, which would be desirable.
Here's the Person object:
public class Person implements PropertyChangeListener { private String name; public static final String PROP_NAME = "name"; public Person(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { String oldName = this.name; this.name = name; propertyChangeSupport.firePropertyChange(PROP_NAME, oldName, name); } private transient final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this); public void addPropertyChangeListener(PropertyChangeListener listener) { propertyChangeSupport.addPropertyChangeListener(listener); } public void removePropertyChangeListener(PropertyChangeListener listener) { propertyChangeSupport.removePropertyChangeListener(listener); } @Override public void propertyChange(PropertyChangeEvent evt) { propertyChangeSupport.firePropertyChange(evt); } }
And here's the Node with UndoRedo enablement:
public class PersonNode extends AbstractNode implements UndoRedo.Provider, PropertyChangeListener { private UndoRedo.Manager manager = new UndoRedo.Manager(); private boolean undoRedoEvent; public PersonNode(Person person) { super(Children.LEAF, Lookups.singleton(person)); person.addPropertyChangeListener(this); setDisplayName(person.getName()); } @Override protected Sheet createSheet() { Sheet sheet = Sheet.createDefault(); Sheet.Set set = Sheet.createPropertiesSet(); set.put(new NameProperty(getLookup().lookup(Person.class))); sheet.put(set); return sheet; } @Override public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equals(Person.PROP_NAME)) { firePropertyChange(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue()); } } public void fireUndoableEvent(String property, Person source, Object oldValue, Object newValue) { manager.addEdit(new MyAbstractUndoableEdit(source, oldValue, newValue)); } @Override public UndoRedo getUndoRedo() { return manager; } @Override public String getDisplayName() { Person p = getLookup().lookup(Person.class); if (p != null) { return p.getName(); } return super.getDisplayName(); } private class NameProperty extends PropertySupport.ReadWrite<String> { private Person p; public NameProperty(Person p) { super("name", String.class, "Name", "Name of Person"); this.p = p; } @Override public String getValue() throws IllegalAccessException, InvocationTargetException { return p.getName(); } @Override public void setValue(String newValue) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { String oldValue = p.getName(); p.setName(newValue); if (!undoRedoEvent) { fireUndoableEvent("name", p, oldValue, newValue); fireDisplayNameChange(oldValue, newValue); } } } class MyAbstractUndoableEdit extends AbstractUndoableEdit { private final String oldValue; private final String newValue; private final Person source; private MyAbstractUndoableEdit(Person source, Object oldValue, Object newValue) { this.oldValue = oldValue.toString(); this.newValue = newValue.toString(); this.source = source; } @Override public boolean canRedo() { return true; } @Override public boolean canUndo() { return true; } @Override public void undo() throws CannotUndoException { undoRedoEvent = true; source.setName(oldValue.toString()); fireDisplayNameChange(oldValue, newValue); undoRedoEvent = false; } @Override public void redo() throws CannotUndoException { undoRedoEvent = true; source.setName(newValue.toString()); fireDisplayNameChange(oldValue, newValue); undoRedoEvent = false; } } }
Does anyone out there know how to have the Undo/Redo functionality enabled when the Properties Window is selected?
© Oracle Blogs or respective owner