KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > xml > schema > ui > nodes > RefreshableChildren


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.xml.schema.ui.nodes;
21
22 import java.util.ArrayList JavaDoc;
23 import java.util.List JavaDoc;
24 import javax.swing.event.ChangeEvent JavaDoc;
25 import javax.swing.event.ChangeListener JavaDoc;
26 import org.netbeans.modules.xml.schema.model.SchemaComponent;
27 import org.netbeans.modules.xml.schema.ui.nodes.categorized.CategoryNode;
28 import org.netbeans.modules.xml.xam.Model;
29 import org.openide.nodes.Children;
30 import org.openide.nodes.Index;
31 import org.openide.nodes.Node;
32
33 /**
34  * Represents a Children that can be rebuilt on demand. Also implements
35  * the Index cookie to allow re-ordering of the children. To enable, the
36  * instance must be added to the lookup (cookie set) of the parent Node.
37  *
38  * @author Todd Fast, todd.fast@sun.com
39  * @author Nathan Fiedler
40  */

41 public abstract class RefreshableChildren extends Children.Keys implements Index {
42     /** Permits changing order of children. */
43     private Index indexSupport;
44
45     /**
46      * Creates a new instance of RefreshableChildren.
47      */

48     public RefreshableChildren() {
49         super();
50         indexSupport = new IndexSupport();
51     }
52
53     /**
54      * Refresh the children.
55      */

56     public abstract void refreshChildren();
57
58     public void addChangeListener(ChangeListener JavaDoc l) {
59         indexSupport.addChangeListener(l);
60     }
61
62     public void removeChangeListener(ChangeListener JavaDoc l) {
63         indexSupport.removeChangeListener(l);
64     }
65
66     public void exchange(int x, int y) {
67         indexSupport.exchange(x, y);
68     }
69
70     public int indexOf(Node node) {
71         return indexSupport.indexOf(node);
72     }
73
74     public void moveUp(int i) {
75         indexSupport.moveUp(i);
76     }
77
78     public void moveDown(int i) {
79         indexSupport.moveDown(i);
80     }
81
82     public void move(int x, int y) {
83         indexSupport.move(x, y);
84     }
85
86     public void reorder() {
87         indexSupport.reorder();
88     }
89
90     public void reorder(int[] i) {
91         indexSupport.reorder(i);
92     }
93
94     /**
95      * Allows re-ordering of the child nodes.
96      */

97     private class IndexSupport extends Index.Support {
98
99         public void reorder(int[] perm) {
100             // Moving the last node of five to the second position results
101
// in an array that looks like: [0, 2, 3, 4, 1]
102
// This means that the first node stays first, the second
103
// node is now third, and so on, while the last node is
104
// now in the second position.
105

106             // Because some nodes present the children of their only child
107
// (e.g. simple type node), we need to get the node children
108
// and ask the first one for its schema component. We assume
109
// there is at least one child (otherwise this method would not
110
// be invoked) and that all of the children have a common parent.
111
Node[] nodes = getNodes();
112             SchemaComponentNode scn = (SchemaComponentNode) nodes[0].
113                     getCookie(SchemaComponentNode.class);
114             SchemaComponent parent = null;
115             if (scn != null) {
116                 parent = scn.getReference().get().getParent();
117             } else {
118                 // Not a schema component node? May be a category node.
119
CategoryNode cn = (CategoryNode) getNode().
120                         getCookie(CategoryNode.class);
121                 if (cn != null) {
122                     parent = cn.getReference().get();
123                 }
124                 // Else, it is unknown and we cannot reorder its children.
125
}
126             if (parent != null) {
127                 // Re-order the children in the model and let the nodes get
128
// refreshed via the listeners.
129
Model model = parent.getModel();
130                 try {
131                     model.startTransaction();
132                     List JavaDoc<SchemaComponent> children = parent.getChildren();
133                     // Need to create a copy of the list since we would
134
// otherwise be mutating it locally and via the model.
135
children = new ArrayList JavaDoc<SchemaComponent>(children);
136                     SchemaComponent[] arr = children.toArray(
137                             new SchemaComponent[children.size()]);
138                     for (int i = 0; i < arr.length; i++) {
139                         children.set(perm[i], arr[i]);
140                     }
141                     // Make copies of the children. Need to make a copy,
142
// otherwise model says we are adding a node that is
143
// already a part of the tree.
144
List JavaDoc<SchemaComponent> copies = new ArrayList JavaDoc<SchemaComponent>();
145                     for (SchemaComponent child : children) {
146                         copies.add((SchemaComponent)child.copy(parent));
147                     }
148                     // Cannot remove children until after they are copied.
149
for (SchemaComponent child : children) {
150                         model.removeChildComponent(child);
151                     }
152                     // Now add the copies back to the parent.
153
for (SchemaComponent copy : copies) {
154                         model.addChildComponent(parent, copy, -1);
155                     }
156                 } catch (IndexOutOfBoundsException JavaDoc ioobe) {
157                     // This occurs for redefine node when user drags and drops.
158
// Need to silently fail, as with reordering category nodes.
159
return;
160                 } finally {
161                     model.endTransaction();
162                 }
163                 // Notify listeners of the change.
164
fireChangeEvent(new ChangeEvent JavaDoc(this));
165             }
166             // Else silently fail, as with reordering within category nodes.
167
}
168
169         public int getNodesCount() {
170             return RefreshableChildren.this.getNodesCount();
171         }
172
173         public Node[] getNodes() {
174             return RefreshableChildren.this.getNodes();
175         }
176     }
177 }
178
Popular Tags