http://blogs.oracle.com/geertjan/?page=9
————————————————————————————————————————————————————————————————————————
This time, for the first time in my blog, via Children.Keys:
public class MyObjectChildren extends Children.Keys<MyObject> implements Index {
private Index indexSupport;
@Override
protected void addNotify() {
MyObject p1 = new MyObject("bla1");
MyObject p2 = new MyObject("bla2");
MyObject p3 = new MyObject("bla3");
ArrayList<MyObject> s = new ArrayList<MyObject>();
s.add(p1);
s.add(p2);
s.add(p3);
indexSupport = new IndexSupport(s, getNode());
setKeys(s);
}
@Override
protected Node[] createNodes(MyObject t) {
return new Node[]{new MyObjectNode(t)};
}
private class MyObjectNode extends AbstractNode {
public MyObjectNode(MyObject key) {
super(Children.LEAF);
setDisplayName(key.getName());
}
@Override
public Action[] getActions(boolean popup) {
return new Action[]{
SystemAction.get(MoveUpAction.class),
SystemAction.get(MoveDownAction.class)
};
}
}
@Override
public void addChangeListener(ChangeListener l) {
indexSupport.addChangeListener(l);
}
@Override
public void removeChangeListener(ChangeListener l) {
indexSupport.removeChangeListener(l);
}
@Override
public void exchange(int x, int y) {
indexSupport.exchange(x, y);
}
@Override
public int indexOf(Node node) {
return indexSupport.indexOf(node);
}
@Override
public void moveUp(int i) {
indexSupport.moveUp(i);
}
@Override
public void moveDown(int i) {
indexSupport.moveDown(i);
}
@Override
public void move(int x, int y) {
indexSupport.move(x, y);
}
@Override
public void reorder() {
indexSupport.reorder();
}
@Override
public void reorder(int[] i) {
indexSupport.reorder(i);
}
private class IndexSupport extends Index.Support {
ArrayList keyArrayList;
Node myNode;
IndexSupport(ArrayList keyArrayList, Node myNode) {
this.keyArrayList = keyArrayList;
this.myNode = myNode;
}
@Override
public void reorder(int[] perm) {
ArrayList newOrder = new ArrayList();
for (int i = 0; i < keyArrayList.size(); i++) {
newOrder.add(keyArrayList.get(perm[i]));
}
keyArrayList.clear();
keyArrayList.addAll(newOrder);
setKeys(newOrder);
}
@Override
public int getNodesCount() {
return myNode.getChildren().getNodesCount();
}
@Override
public Node[] getNodes() {
return myNode.getChildren().getNodes();
}
}
}
private Index indexSupport;
@Override
protected void addNotify() {
MyObject p1 = new MyObject("bla1");
MyObject p2 = new MyObject("bla2");
MyObject p3 = new MyObject("bla3");
ArrayList<MyObject> s = new ArrayList<MyObject>();
s.add(p1);
s.add(p2);
s.add(p3);
indexSupport = new IndexSupport(s, getNode());
setKeys(s);
}
@Override
protected Node[] createNodes(MyObject t) {
return new Node[]{new MyObjectNode(t)};
}
private class MyObjectNode extends AbstractNode {
public MyObjectNode(MyObject key) {
super(Children.LEAF);
setDisplayName(key.getName());
}
@Override
public Action[] getActions(boolean popup) {
return new Action[]{
SystemAction.get(MoveUpAction.class),
SystemAction.get(MoveDownAction.class)
};
}
}
@Override
public void addChangeListener(ChangeListener l) {
indexSupport.addChangeListener(l);
}
@Override
public void removeChangeListener(ChangeListener l) {
indexSupport.removeChangeListener(l);
}
@Override
public void exchange(int x, int y) {
indexSupport.exchange(x, y);
}
@Override
public int indexOf(Node node) {
return indexSupport.indexOf(node);
}
@Override
public void moveUp(int i) {
indexSupport.moveUp(i);
}
@Override
public void moveDown(int i) {
indexSupport.moveDown(i);
}
@Override
public void move(int x, int y) {
indexSupport.move(x, y);
}
@Override
public void reorder() {
indexSupport.reorder();
}
@Override
public void reorder(int[] i) {
indexSupport.reorder(i);
}
private class IndexSupport extends Index.Support {
ArrayList keyArrayList;
Node myNode;
IndexSupport(ArrayList keyArrayList, Node myNode) {
this.keyArrayList = keyArrayList;
this.myNode = myNode;
}
@Override
public void reorder(int[] perm) {
ArrayList newOrder = new ArrayList();
for (int i = 0; i < keyArrayList.size(); i++) {
newOrder.add(keyArrayList.get(perm[i]));
}
keyArrayList.clear();
keyArrayList.addAll(newOrder);
setKeys(newOrder);
}
@Override
public int getNodesCount() {
return myNode.getChildren().getNodesCount();
}
@Override
public Node[] getNodes() {
return myNode.getChildren().getNodes();
}
}
}
Import statements:
import java.util.ArrayList;
import javax.swing.Action;
import javax.swing.event.ChangeListener;
import org.openide.actions.MoveDownAction;
import org.openide.actions.MoveUpAction;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children;
import org.openide.nodes.Index;
import org.openide.nodes.Node;
import org.openide.util.actions.SystemAction;
import javax.swing.Action;
import javax.swing.event.ChangeListener;
import org.openide.actions.MoveDownAction;
import org.openide.actions.MoveUpAction;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children;
import org.openide.nodes.Index;
import org.openide.nodes.Node;
import org.openide.util.actions.SystemAction;
This is a terribly misleading example because it conflates the view with the model; the demo is not just incidentally useless, it cannot even look similar to any useful code.
What you want to demonstrate is a POJO model which has a meaningfully reorderable list of objects. An impl of Index (added to the parent node's lookup) would reorder that model, to which the children (ChildFactory would work just as well) would respond without any special code. Chapter 25 in "NetBeans: The Definitive Guide" did this years ago: https://hg.netbeans.org/main/misc/raw-file/default/platform/samples/minicomposer/src/org/netbeans/examples/modules/minicomposer/ScoreChildren.java
Posted by Jesse Glick on January 14, 2011 at 05:55 AM PST #
What is an example of a meaningfully reorderable list of objects?
Posted by Geertjan Wielenga on January 14, 2011 at 06:33 AM PST #
Well, notes in a score in the above example. If you drag and drop note nodes under the score node, the score itself is rearranged, which the score children of course reflects.
Posted by Jesse Glick on January 14, 2011 at 06:38 AM PST #
First thank you for this example.
Does this example work also with subnodes ? because I mixed it with this tutorial "http://platform.netbeans.org/tutorials/nbm-nodesapi2.html" and MoveUp/MoveDown actions are disabled on subnodes!!
Maybe I miss something in the lookup of the explorermanager rootcontext, but what?
Anyway, based on this example, I mainly try to do the MoveUp and MoveDown action with the mouse, I can drag the node but it never drops !!!
Are these actions are the same? I tried with NodeListener to hook the drop event in the tree without success.. any idea ?
Thank you.
Posted by d3d3 on January 20, 2011 at 06:55 AM PST #
After a very restful week-end.. to respond to myself, I used the beannode instead of the abstractnode, so to work with all nodes, I only have to add to the beannode constructor an implementation of the Index.Support in the Lookup ! and also, don't forget to override the methods canCut and canCopy to return true.
Posted by d3d3 on January 23, 2011 at 11:46 PM PST #
the ordering wasnt right, so i refactored to this.
@Override
public void reorder(int[] perm) {
ArrayList clone = new ArrayList();
clone.addAll(keyArrayList);
for (int i = 0; i < keyArrayList.size(); i++) {
keyArrayList.set(perm[i], clone.get(i));
}
setKeys(keyArrayList);
}
Posted by heidtmare on July 28, 2011 at 02:05 PM PDT #