diff -r o -r p -r e -r n -r i -r d -r e -r . -r e -r x -r p -r l -r o -r r -r e -r r -r / -r s -r r -r c -r / -r o -r r -r g -r / -r o -r p -r e -r n -r i -r d -r e -r / -r e -r x -r p -r l -r o -r r -r e -r r -r / -r v -r i -r e -r w -r / -r N -r o -r d -r e -r L -r i -r s -r t -r M -r o -r d -r e -r l -r . -r j -r a -r v -r a openide.explorer/src/org/openide/explorer/view/NodeListModel.java
--- a/openide.explorer/src/org/openide/explorer/view/NodeListModel.java
+++ b/openide.explorer/src/org/openide/explorer/view/NodeListModel.java
@@ -158,7 +158,6 @@ public class NodeListModel extends Abstr
if (listener == null) {
listener = new Listener(this);
}
-
return listener;
}
@@ -170,7 +169,6 @@ public class NodeListModel extends Abstr
*/
public int getSize() {
int s = findSize(parent, -1, depth);
-
return s;
}
@@ -186,9 +184,7 @@ public class NodeListModel extends Abstr
*/
public int getIndex(Object o) {
getSize();
-
Info i = childrenCount.get(o);
-
return (i == null) ? (-1) : i.index;
}
@@ -221,7 +217,6 @@ public class NodeListModel extends Abstr
*/
private int findSize(VisualizerNode vis, int index, int depth) {
Info info = childrenCount.get(vis);
-
if (info != null) {
return info.childrenCount;
}
@@ -233,15 +228,16 @@ public class NodeListModel extends Abstr
info.depth = depth;
info.index = index;
+ /*if (depth == 1) {
+ // enough to know the number of children
+ size += vis.getChildren().getChildCount();
+ } else */
if (depth-- > 0) {
- Iterator it = vis.getChildren().iterator();
-
- while (it.hasNext()) {
- VisualizerNode v = (VisualizerNode) it.next();
-
+ Enumeration it = vis.getChildren().children();
+ while (it.hasMoreElements()) {
+ VisualizerNode v = (VisualizerNode) it.nextElement();
// count node v
size++;
-
// now count children of node v
size += findSize(v, index + size, depth);
}
@@ -249,7 +245,6 @@ public class NodeListModel extends Abstr
info.childrenCount = size;
childrenCount.put(vis, info);
-
return size;
}
@@ -266,10 +261,9 @@ public class NodeListModel extends Abstr
return (VisualizerNode) vis.getChildAt(indx);
}
- Iterator it = vis.getChildren().iterator();
-
- while (it.hasNext()) {
- VisualizerNode v = (VisualizerNode) it.next();
+ Enumeration it = vis.getChildren().children();
+ while (it.hasMoreElements()) {
+ VisualizerNode v = (VisualizerNode) it.nextElement();
if (indx-- == 0) {
return v;
diff -r o -r p -r e -r n -r i -r d -r e -r . -r e -r x -r p -r l -r o -r r -r e -r r -r / -r s -r r -r c -r / -r o -r r -r g -r / -r o -r p -r e -r n -r i -r d -r e -r / -r e -r x -r p -r l -r o -r r -r e -r r -r / -r v -r i -r e -r w -r / -r T -r r -r e -r e -r V -r i -r e -r w -r . -r j -r a -r v -r a openide.explorer/src/org/openide/explorer/view/TreeView.java
--- a/openide.explorer/src/org/openide/explorer/view/TreeView.java
+++ b/openide.explorer/src/org/openide/explorer/view/TreeView.java
@@ -296,6 +296,7 @@ public abstract class TreeView extends J
// Init of the editor
tree.setCellEditor(new TreeViewCellEditor(tree));
tree.setEditable(true);
+ tree.setLargeModel(true);
// set selection mode to DISCONTIGUOUS_TREE_SELECTION as default
setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
@@ -842,21 +843,18 @@ public abstract class TreeView extends J
showWaitCursor();
RequestProcessor.getDefault().post(new Runnable() {
- public void run() {
- try {
- node.getChildren().getNodes(true);
- }
- catch (Exception e) {
- // log a exception
- Logger.getLogger(TreeView.class.getName()).log(Level.WARNING,
- null, e);
- }
- finally {
- // show normal cursor above all
- showNormalCursor();
- }
- }
- });
+ public void run() {
+ try {
+ node.getChildren().getNodesCount(true);
+ } catch (Exception e) {
+ // log a exception
+ Logger.getLogger(TreeView.class.getName()).log(Level.WARNING, null, e);
+ } finally {
+ // show normal cursor above all
+ showNormalCursor();
+ }
+ }
+ });
}
/** Synchronize the selected nodes from the manager of this Explorer.
diff -r o -r p -r e -r n -r i -r d -r e -r . -r e -r x -r p -r l -r o -r r -r e -r r -r / -r s -r r -r c -r / -r o -r r -r g -r / -r o -r p -r e -r n -r i -r d -r e -r / -r e -r x -r p -r l -r o -r r -r e -r r -r / -r v -r i -r e -r w -r / -r V -r i -r s -r u -r a -r l -r i -r z -r e -r r -r C -r h -r i -r l -r d -r r -r e -r n -r . -r j -r a -r v -r a openide.explorer/src/org/openide/explorer/view/VisualizerChildren.java
--- a/openide.explorer/src/org/openide/explorer/view/VisualizerChildren.java
+++ b/openide.explorer/src/org/openide/explorer/view/VisualizerChildren.java
@@ -41,7 +41,6 @@ package org.openide.explorer.view;
package org.openide.explorer.view;
import org.openide.nodes.*;
-
import java.util.*;
@@ -51,35 +50,118 @@ import java.util.*;
* @author Jaroslav Tulach
*/
final class VisualizerChildren extends Object {
+ /** empty visualizer children for any leaf */
+ public static final VisualizerChildren EMPTY = new VisualizerChildren();
+
/** parent visualizer */
public final VisualizerNode parent;
- /** list of all objects here (VisualizerNode) */
-public final List<VisualizerNode> list = new ArrayList<VisualizerNode>();
+ /** visualizer nodes (children) */
+ private final List<VisualizerNode> visNodes;
+ /** Empty VisualizerChildren. */
+ private VisualizerChildren () {
+ visNodes = Collections.EMPTY_LIST;
+ parent = null;
+ }
+
/** Creates new VisualizerChildren.
- * Can be called only from EventQueue.
- */
- public VisualizerChildren(VisualizerNode parent, Node[] nodes) {
+ * Can be called only from EventQueue.
+ */
+ public VisualizerChildren(VisualizerNode parent, int size) {
this.parent = parent;
-
- int s = nodes.length;
-
- for (int i = 0; i < s; i++) {
- VisualizerNode v = VisualizerNode.getVisualizer(this, nodes[i]);
- list.add(v);
+ visNodes = new ArrayList<VisualizerNode>(size);
+ for (int i = 0; i < size; i++) {
+ visNodes.add(null);
}
}
+ /** recomputes indexes for all nodes.
+ * @param tn tree node that we are looking for
+ * @return true if there is non-null object inside
+ */
+ private final boolean recomputeIndexes(VisualizerNode tn) {
+ assert tn == null || this.parent == tn.getParent() : "tn must be our child!"; // NOI18N
+
+ boolean isNonNull = false;
+ for (int i = 0; i < visNodes.size(); i++) {
+ VisualizerNode node = (VisualizerNode) visNodes.get(i);
+ if (node != null) {
+ node.indexOf = i;
+ isNonNull = true;
+ }
+ }
+
+ if (tn != null && tn.indexOf == -1) {
+ // not computed => force computation
+ for (int i = 0; i < visNodes.size(); i++) {
+ VisualizerNode visNode = (VisualizerNode) getChildAt(i);
+ visNode.indexOf = i;
+ if (visNode == tn) {
+ return isNonNull;
+ }
+ }
+ }
+ return isNonNull;
+ }
+
+ public javax.swing.tree.TreeNode getChildAt(int pos) {
+ VisualizerNode visNode = visNodes.get(pos);
+ if (visNode == null) {
+ Node node = parent.node.getChildren().getNodeAt(pos);
+ if (node == null) {
+ return VisualizerNode.EMPTY;
+ }
+ visNode = VisualizerNode.getVisualizer(this, node);
+ visNode.indexOf = pos;
+ visNodes.set(pos, visNode);
+ }
+ return visNode;
+ }
+
+ public int getChildCount() {
+ return visNodes.size();
+ }
+
+ public java.util.Enumeration children() {
+ return new java.util.Enumeration() {
+
+ private int index;
+
+ public boolean hasMoreElements() {
+ return index < visNodes.size();
+ }
+
+ public Object nextElement() {
+ return getChildAt(index++);
+ }
+ };
+ }
+
+ /** Delegated to us from VisualizerNode
+ *
+ */
+ public int getIndex(final javax.swing.tree.TreeNode p1) {
+ VisualizerNode visNode = (VisualizerNode) p1;
+ if (visNode.getParent() != this.parent) {
+ return -1;
+ }
+
+ if (visNode.indexOf == -1) {
+ recomputeIndexes(visNode);
+ }
+ assert visNode.indexOf != -1 : "Index of v has been computed by recomputeIndexes"; // NOI18N
+ return visNode.indexOf;
+ }
+
/** Notification of children addded event. Modifies the list of nodes
- * and fires info to all listeners.
- */
+ * and fires info to all listeners.
+ */
public void added(VisualizerEvent.Added ev) {
- ListIterator<VisualizerNode> it = list.listIterator();
+ ListIterator<VisualizerNode> it = visNodes.listIterator();
boolean empty = !it.hasNext();
int[] indxs = ev.getArray();
- Node[] nodes = ev.getAdded();
int current = 0;
int inIndxs = 0;
@@ -88,47 +170,33 @@ public final List<VisualizerNode> list =
while (current++ < indxs[inIndxs]) {
it.next();
}
-
- it.add(VisualizerNode.getVisualizer(this, nodes[inIndxs]));
+ it.add(null);
inIndxs++;
}
+ boolean isNonNull = recomputeIndexes(null);
+
VisualizerNode parent = this.parent;
-
while (parent != null) {
Object[] listeners = parent.getListenerList();
-
for (int i = listeners.length - 1; i >= 0; i -= 2) {
((NodeModel) listeners[i]).added(ev);
}
-
parent = (VisualizerNode) parent.getParent();
}
-
if (empty) {
// change of state
- this.parent.notifyVisualizerChildrenChange(list.size(), this);
+ this.parent.notifyVisualizerChildrenChange(isNonNull, this);
}
}
- private static boolean sameContains(List l, Object elem) {
- for (Iterator it = l.iterator(); it.hasNext();) {
- if (it.next() == elem) {
- return true;
- }
- }
-
- return false;
- }
-
/** Notification that children has been removed. Modifies the list of nodes
- * and fires info to all listeners.
- */
+ * and fires info to all listeners.
+ */
public void removed(VisualizerEvent.Removed ev) {
+ /*
List remList = Arrays.asList(ev.getRemovedNodes());
-
- Iterator it = list.iterator();
-
+ Iterator it = visNodes.iterator();
VisualizerNode vis;
int[] indx = new int[remList.size()];
@@ -140,37 +208,38 @@ public final List<VisualizerNode> list =
vis = (VisualizerNode) it.next();
// check if it will removed
- if (sameContains(remList, vis.node)) {
+ if (remList.contains(vis.node)) {
indx[remSize++] = count;
-
// remove this VisualizerNode from children
it.remove();
-
// bugfix #36389, add the removed node to VisualizerEvent
ev.removed.add(vis);
}
-
count++;
}
+ ev.setRemovedIndicies(indx);*/
+
+ int[] idxs = ev.getArray();
+ for (int i = idxs.length - 1; i >= 0; i--) {
+ VisualizerNode visNode = visNodes.remove(idxs[i]);
+ ev.removed.add(visNode);
+ }
// notify event about changed indexes
- ev.setRemovedIndicies(indx);
+ recomputeIndexes(null);
VisualizerNode parent = this.parent;
-
while (parent != null) {
Object[] listeners = parent.getListenerList();
-
for (int i = listeners.length - 1; i >= 0; i -= 2) {
((NodeModel) listeners[i]).removed(ev);
}
-
parent = (VisualizerNode) parent.getParent();
}
- if (list.isEmpty()) {
+ if (visNodes.isEmpty()) {
// now is empty
- this.parent.notifyVisualizerChildrenChange(0, this);
+ this.parent.notifyVisualizerChildrenChange(true, this);
}
}
@@ -180,35 +249,31 @@ public final List<VisualizerNode> list =
* which may be in an inconsistent state.
*/
private int[] reorderByComparator(Comparator<VisualizerNode> c) {
- VisualizerNode[] old = list.toArray(new VisualizerNode[list.size()]);
+ VisualizerNode[] old = visNodes.toArray(new VisualizerNode[visNodes.size()]);
Arrays.sort(old, c);
int[] idxs = new int[old.length];
-
for (int i = 0; i < idxs.length; i++) {
- idxs[i] = list.indexOf(old[i]);
+ idxs[i] = visNodes.indexOf(old[i]);
}
- list.clear();
- list.addAll(Arrays.asList(old));
-
+ visNodes.clear();
+ visNodes.addAll(Arrays.asList(old));
return idxs;
}
/** Notification that children has been reordered. Modifies the list of nodes
- * and fires info to all listeners.
- */
+ * and fires info to all listeners.
+ */
public void reordered(VisualizerEvent.Reordered ev) {
if (ev.getComparator() != null) {
//#37802
ev.array = reorderByComparator(ev.getComparator());
} else {
int[] indxs = ev.getArray();
- VisualizerNode[] old = list.toArray(new VisualizerNode[list.size()]);
+ VisualizerNode[] old = visNodes.toArray(new VisualizerNode[visNodes.size()]);
VisualizerNode[] arr = new VisualizerNode[old.length];
-
int s = indxs.length;
-
try {
for (int i = 0; i < s; i++) {
// arr[indxs[i]] = old[i];
@@ -244,21 +309,20 @@ public final List<VisualizerNode> list =
}
assert !Arrays.asList(arr).contains(null) : "Null element in reorderer list " + Arrays.asList(arr) +
- "; list=" + list + " indxs=" + Arrays.asList(org.openide.util.Utilities.toObjectArray(indxs));
- list.clear();
- list.addAll(Arrays.asList(arr));
- assert !list.contains(null);
+ "; list=" + visNodes + " indxs=" + Arrays.asList(org.openide.util.Utilities.toObjectArray(indxs));
+ visNodes.clear();
+ visNodes.addAll(Arrays.asList(arr));
+ assert !visNodes.contains(null);
}
+ recomputeIndexes(null);
VisualizerNode parent = this.parent;
while (parent != null) {
Object[] listeners = parent.getListenerList();
-
for (int i = listeners.length - 1; i >= 0; i -= 2) {
((NodeModel) listeners[i]).reordered(ev);
}
-
parent = (VisualizerNode) parent.getParent();
}
}
diff -r o -r p -r e -r n -r i -r d -r e -r . -r e -r x -r p -r l -r o -r r -r e -r r -r / -r s -r r -r c -r / -r o -r r -r g -r / -r o -r p -r e -r n -r i -r d -r e -r / -r e -r x -r p -r l -r o -r r -r e -r r -r / -r v -r i -r e -r w -r / -r V -r i -r s -r u -r a -r l -r i -r z -r e -r r -r E -r v -r e -r n -r t -r . -r j -r a -r v -r a openide.explorer/src/org/openide/explorer/view/VisualizerEvent.java
--- a/openide.explorer/src/org/openide/explorer/view/VisualizerEvent.java
+++ b/openide.explorer/src/org/openide/explorer/view/VisualizerEvent.java
@@ -53,7 +53,7 @@ import java.util.LinkedList;
* @author Jaroslav Tulach
*/
abstract class VisualizerEvent extends EventObject {
- /** indicies */
+ /** indices */
int[] array;
public VisualizerEvent(VisualizerChildren ch, int[] array) {
@@ -84,23 +84,12 @@ abstract class VisualizerEvent extends E
static final class Added extends VisualizerEvent implements Runnable {
static final long serialVersionUID = 5906423476285962043L;
- /** array of newly added nodes */
- private Node[] added;
-
- /** Constructor for add of nodes notification.
+ /** Constructor for nodes adding notification.
* @param ch children
- * @param n array of added nodes
- * @param indx indicies of added nodes
+ * @param idxs indicies of added nodes
*/
- public Added(VisualizerChildren ch, Node[] n, int[] indx) {
- super(ch, indx);
- added = n;
- }
-
- /** Getter for added nodes.
- */
- public Node[] getAdded() {
- return added;
+ public Added(VisualizerChildren ch, int[] idxs) {
+ super(ch, idxs);
}
/** Process the event
@@ -119,24 +108,13 @@ abstract class VisualizerEvent extends E
/** linked list of removed nodes, that is filled in getChildren ().removed () method
*/
public LinkedList<VisualizerNode> removed = new LinkedList<VisualizerNode>();
- private Node[] removedNodes;
- /** Constructor for add of nodes notification.
+ /** Constructor for nodes removal notification.
* @param ch children
- * @param n array of added nodes
- * @param indx indicies of added nodes
+ * @param idxs indicies of added nodes
*/
- public Removed(VisualizerChildren ch, Node[] removedNodes) {
- super(ch, null);
- this.removedNodes = removedNodes;
- }
-
- public Node[] getRemovedNodes() {
- return removedNodes;
- }
-
- public void setRemovedIndicies(int[] arr) {
- super.array = arr;
+ public Removed(VisualizerChildren ch, int[] idxs) {
+ super(ch, idxs);
}
/** Process the event
@@ -153,13 +131,12 @@ abstract class VisualizerEvent extends E
static final long serialVersionUID = -4572356079752325870L;
private Comparator<VisualizerNode> comparator = null;
- /** Constructor for add of nodes notification.
+ /** Constructor for nodes reordering notification.
* @param ch children
- * @param n array of added nodes
* @param indx indicies of added nodes
*/
- public Reordered(VisualizerChildren ch, int[] indx) {
- super(ch, indx);
+ public Reordered(VisualizerChildren ch, int[] idxs) {
+ super(ch, idxs);
}
//#37802 - provide a way to just send a comparator along to do the
diff -r o -r p -r e -r n -r i -r d -r e -r . -r e -r x -r p -r l -r o -r r -r e -r r -r / -r s -r r -r c -r / -r o -r r -r g -r / -r o -r p -r e -r n -r i -r d -r e -r / -r e -r x -r p -r l -r o -r r -r e -r r -r / -r v -r i -r e -r w -r / -r V -r i -r s -r u -r a -r l -r i -r z -r e -r r -r N -r o -r d -r e -r . -r j -r a -r v -r a openide.explorer/src/org/openide/explorer/view/VisualizerNode.java
--- a/openide.explorer/src/org/openide/explorer/view/VisualizerNode.java
+++ b/openide.explorer/src/org/openide/explorer/view/VisualizerNode.java
@@ -118,6 +118,9 @@ final class VisualizerNode extends Event
/** the VisualizerChildren that contains this VisualizerNode or null */
private VisualizerChildren parent;
+ /** index in parent */
+ int indexOf = -1;
+
/** cached name */
private String name;
@@ -242,13 +245,13 @@ final class VisualizerNode extends Event
/** Getter for list of children of this visualizer.
* @return list of VisualizerNode objects
*/
- public List<VisualizerNode> getChildren() {
+ public VisualizerChildren getChildren() {
VisualizerChildren ch = children.get();
if ((ch == null) && !node.isLeaf()) {
- // initialize the nodes children before we enter
- // the readAccess section
- Node[] tmpInit = node.getChildren().getNodes();
+ // initialize the nodes children before we enter the readAccess section
+ // (otherwise we could receive invalid node count (under lock))
+ final int count = node.getChildren().getNodesCount();
// go into lock to ensure that no childrenAdded, childrenRemoved,
// childrenReordered notifications occures and that is why we do
@@ -256,29 +259,22 @@ final class VisualizerNode extends Event
ch = Children.MUTEX.readAccess(
new Mutex.Action<VisualizerChildren>() {
public VisualizerChildren run() {
- Node[] nodes = node.getChildren().getNodes();
- VisualizerChildren vc = new VisualizerChildren(VisualizerNode.this, nodes);
- notifyVisualizerChildrenChange(nodes.length, vc);
-
+ int nodesCount = node.getChildren().getNodesCount();
+ VisualizerChildren vc = new VisualizerChildren(VisualizerNode.this, nodesCount);
+ notifyVisualizerChildrenChange(true, vc);
return vc;
}
}
);
}
-
- if (LOG.isLoggable(Level.FINER)) {
- // this assert is too expensive during the performance tests:
- assert (ch == null) || !ch.list.contains(null) : ch.list + " from " + node;
- }
-
- return (ch == null) ? Collections.<VisualizerNode>emptyList() : ch.list;
+ return ch == null ? VisualizerChildren.EMPTY : ch;
}
//
// TreeNode interface (callable only from AWT-Event-Queue)
//
public int getIndex(final javax.swing.tree.TreeNode p1) {
- return getChildren().indexOf(p1);
+ return getChildren().getIndex(p1);
}
public boolean getAllowsChildren() {
@@ -286,22 +282,15 @@ final class VisualizerNode extends Event
}
public javax.swing.tree.TreeNode getChildAt(int p1) {
- List ch = getChildren();
- VisualizerNode vn = (VisualizerNode) ch.get(p1);
- assert vn != null : "Null child in " + ch + " from " + node;
-
- return vn;
+ return getChildren().getChildAt(p1);
}
public int getChildCount() {
- return getChildren().size();
+ return getChildren().getChildCount();
}
public java.util.Enumeration<VisualizerNode> children() {
- List<VisualizerNode> l = getChildren();
- assert !l.contains(null) : "Null child in " + l + " from " + node;
-
- return java.util.Collections.enumeration(l);
+ return getChildren().children();
}
public boolean isLeaf() {
@@ -330,7 +319,7 @@ final class VisualizerNode extends Event
return;
}
- QUEUE.runSafe(new VisualizerEvent.Added(ch, ev.getDelta(), ev.getDeltaIndices()));
+ QUEUE.runSafe(new VisualizerEvent.Added(ch, ev.getDeltaIndices()));
LOG.log(Level.FINER, "childrenAdded - end"); // NOI18N
}
@@ -346,7 +335,7 @@ final class VisualizerNode extends Event
return;
}
- QUEUE.runSafe(new VisualizerEvent.Removed(ch, ev.getDelta()));
+ QUEUE.runSafe(new VisualizerEvent.Removed(ch, ev.getDeltaIndices()));
LOG.log(Level.FINER, "childrenRemoved - end"); // NOI18N
}
@@ -486,8 +475,8 @@ final class VisualizerNode extends Event
* @param size amount of children
* @param ch the children
*/
- void notifyVisualizerChildrenChange(int size, VisualizerChildren ch) {
- if (size == 0) {
+ void notifyVisualizerChildrenChange(boolean strongly, VisualizerChildren ch) {
+ if (strongly) {
// hold the children hard
children = new StrongReference<VisualizerChildren>(ch);
} else {
@@ -513,12 +502,14 @@ final class VisualizerNode extends Event
/** Hash code
*/
+ @Override
public int hashCode() {
return hashCode;
}
/** Equals two objects are equal if they have the same hash code
*/
+ @Override
public boolean equals(Object o) {
if (!(o instanceof VisualizerNode)) {
return false;
@@ -531,6 +522,7 @@ final class VisualizerNode extends Event
/** String name is taken from the node.
*/
+ @Override
public String toString() {
return getDisplayName();
}
@@ -603,6 +595,7 @@ final class VisualizerNode extends Event
this.o = o;
}
+ @Override
public T get() {
return o;
}
diff -r o -r p -r e -r n -r i -r d -r e -r . -r e -r x -r p -r l -r o -r r -r e -r r -r / -r t -r e -r s -r t -r / -r u -r n -r i -r t -r / -r s -r r -r c -r / -r o -r r -r g -r / -r o -r p -r e -r n -r i -r d -r e -r / -r e -r x -r p -r l -r o -r r -r e -r r -r / -r v -r i -r e -r w -r / -r V -r i -r s -r u -r a -r l -r i -r z -r e -r r -r N -r o -r d -r e -r T -r e -r s -r t -r . -r j -r a -r v -r a openide.explorer/test/unit/src/org/openide/explorer/view/VisualizerNodeTest.java
--- a/openide.explorer/test/unit/src/org/openide/explorer/view/VisualizerNodeTest.java
+++ b/openide.explorer/test/unit/src/org/openide/explorer/view/VisualizerNodeTest.java
@@ -47,6 +47,7 @@ import org.netbeans.junit.NbTestCase;
import org.netbeans.junit.NbTestCase;
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children;
+import org.openide.nodes.FilterNode;
import org.openide.nodes.Node;
/** VisualizerNode tests, mostly based on reported bugs.
@@ -101,4 +102,40 @@ public class VisualizerNodeTest extends
assertSame("Icon instances should be same", icon1, icon2);
}
+
+ public void testLazyVisGet() throws Exception {
+ LazyChildren lch = new LazyChildren();
+ AbstractNode a = new AbstractNode(lch);
+
+ TreeNode ta = Visualizer.findVisualizer(a);
+
+ assertEquals("Child check", "c", ta.getChildAt(2).toString());
+ assertEquals("Counter should be 1", 1, lch.cnt);
+ }
+
+ public void testLazyFilterGet() throws Exception {
+ LazyChildren lch = new LazyChildren();
+ AbstractNode a = new AbstractNode(lch);
+ FilterNode fnode = new FilterNode(a);
+
+ TreeNode ta = Visualizer.findVisualizer(fnode);
+
+ assertEquals("Child check", "c", ta.getChildAt(2).toString());
+ assertEquals("Counter should be 1", 1, lch.cnt);
+ }
+
+ static class LazyChildren extends Children.Keys<String> {
+ public LazyChildren() {
+ super(true);
+ setKeys(new String[] {"a", "b", "c"});
+ }
+ int cnt;
+ @Override
+ protected Node[] createNodes(String key) {
+ AbstractNode node = new AbstractNode(LEAF);
+ node.setName(key);
+ cnt++;
+ return new Node[] {node};
+ }
+ }
}
diff -r o -r p -r e -r n -r i -r d -r e -r . -r l -r o -r a -r d -r e -r r -r s -r / -r s -r r -r c -r / -r o -r r -r g -r / -r o -r p -r e -r n -r i -r d -r e -r / -r l -r o -r a -r d -r e -r r -r s -r / -r D -r a -r t -r a -r F -r o -r l -r d -r e -r r -r . -r j -r a -r v -r a openide.loaders/src/org/openide/loaders/DataFolder.java
--- a/openide.loaders/src/org/openide/loaders/DataFolder.java
+++ b/openide.loaders/src/org/openide/loaders/DataFolder.java
@@ -893,7 +893,7 @@ public class DataFolder extends MultiDat
/* Returns count of the nodes.
*/
public int getNodesCount () {
- return node.getChildren().getNodes(FolderChildren.checkChildrenMutex()).length;
+ return node.getChildren().getNodesCount(FolderChildren.checkChildrenMutex());
}
/* Returns array of subnodes
diff -r o -r p -r e -r n -r i -r d -r e -r . -r l -r o -r a -r d -r e -r r -r s -r / -r s -r r -r c -r / -r o -r r -r g -r / -r o -r p -r e -r n -r i -r d -r e -r / -r l -r o -r a -r d -r e -r r -r s -r / -r D -r a -r t -r a -r O -r b -r j -r e -r c -r t -r P -r o -r o -r l -r . -r j -r a -r v -r a openide.loaders/src/org/openide/loaders/DataObjectPool.java
--- a/openide.loaders/src/org/openide/loaders/DataObjectPool.java
+++ b/openide.loaders/src/org/openide/loaders/DataObjectPool.java
@@ -591,26 +591,8 @@ implements ChangeListener {
*/
private final class FSListener extends FileChangeAdapter {
FSListener() {}
- private Collection<Item> getTargets(FileEvent fe) {
- FileObject fo = fe.getFile();
- List<Item> toNotify = new LinkedList<Item>();
- // The FileSystem notifying us about the changes should
- // not hold any lock so we're safe here
- synchronized (DataObjectPool.this) {
- Item itm = map.get(fo);
- if (itm != null) { // the file was someones' primary
- return Collections.singleton(itm); // so notify only owner
- } else { // unknown file or someone secondary
- List<Item> arr = children.get(fo.getParent());
- if (arr != null) {
- return new ArrayList<Item>(arr);
- } else {
- return Collections.emptyList();
- }
- }
- }
- }
+ @Override
public void fileChanged(FileEvent fe) {
if (LISTENER.isLoggable(Level.FINE)) {
LISTENER.fine("fileChanged: " + fe); // NOI18N
@@ -624,6 +606,7 @@ implements ChangeListener {
}
}
+ @Override
public void fileRenamed (FileRenameEvent fe) {
if (LISTENER.isLoggable(Level.FINE)) {
LISTENER.fine("fileRenamed: " + fe); // NOI18N
@@ -637,6 +620,7 @@ implements ChangeListener {
}
}
+ @Override
public void fileDeleted (FileEvent fe) {
if (LISTENER.isLoggable(Level.FINE)) {
LISTENER.fine("fileDeleted: " + fe); // NOI18N
@@ -650,6 +634,7 @@ implements ChangeListener {
}
}
+ @Override
public void fileDataCreated (FileEvent fe) {
if (LISTENER.isLoggable(Level.FINE)) {
LISTENER.fine("fileDataCreated: " + fe); // NOI18N
@@ -664,19 +649,12 @@ implements ChangeListener {
ShadowChangeAdapter.checkBrokenDataShadows(fe);
}
+ @Override
public void fileAttributeChanged (FileAttributeEvent fe) {
- if (LISTENER.isLoggable(Level.FINE)) {
- LISTENER.fine("fileAttributeChanged: " + fe); // NOI18N
- }
- for (Item item : getTargets(fe)) {
- DataObject dobj = item.getDataObjectOrNull();
- if (LISTENER.isLoggable(Level.FINE)) {
- LISTENER.fine(" to: " + dobj); // NOI18N
- }
- if (dobj != null) dobj.notifyAttributeChanged(fe);
- }
+ checkAttributeChanged(fe);
}
+ @Override
public void fileFolderCreated(FileEvent fe) {
if (LISTENER.isLoggable(Level.FINE)) {
LISTENER.fine("fileFolderCreated: " + fe); // NOI18N
@@ -684,6 +662,55 @@ implements ChangeListener {
ShadowChangeAdapter.checkBrokenDataShadows(fe);
}
}
+
+ static private Collection<Item> getTargets(FileEvent fe) {
+ FileObject fo = fe.getFile();
+ // The FileSystem notifying us about the changes should
+ // not hold any lock so we're safe here
+ synchronized (DataObjectPool.POOL) {
+ Item itm = DataObjectPool.POOL.map.get(fo);
+ if (itm != null) { // the file was someones' primary
+ return Collections.singleton(itm); // so notify only owner
+ } else { // unknown file or someone secondary
+ List<Item> arr = DataObjectPool.POOL.children.get(fo.getParent());
+ if (arr != null) {
+ return new ArrayList<Item>(arr);
+ } else {
+ return Collections.emptyList();
+ }
+ /*List<Item> toNotify = new LinkedList<Item>();
+ FileObject parent = fo.getParent();
+ if (parent != null) { // the fo is not root
+ FileObject[] siblings = parent.getChildren();
+ // notify all in folder
+ for (int i = 0; i < siblings.length; i++) {
+ itm = (Item) DataObjectPool.POOL.map.get(siblings[i]);
+ if (itm != null) {
+ toNotify.add(itm);
+ }
+ }
+ }
+ return toNotify;*/
+ }
+ }
+ }
+
+ /** Checks for attribute changes.
+ */
+ public static void checkAttributeChanged(FileAttributeEvent fe) {
+ if (LISTENER.isLoggable(Level.FINE)) {
+ LISTENER.fine("fileAttributeChanged: " + fe); // NOI18N
+ }
+ for (Item item : getTargets(fe)) {
+ DataObject dobj = item.getDataObjectOrNull();
+ if (LISTENER.isLoggable(Level.FINE)) {
+ LISTENER.fine(" to: " + dobj); // NOI18N
+ }
+ if (dobj != null) {
+ dobj.notifyAttributeChanged(fe);
+ }
+ }
+ }
/** Registers new DataObject instance.
* @param fo primary file for obj
diff -r o -r p -r e -r n -r i -r d -r e -r . -r l -r o -r a -r d -r e -r r -r s -r / -r s -r r -r c -r / -r o -r r -r g -r / -r o -r p -r e -r n -r i -r d -r e -r / -r l -r o -r a -r d -r e -r r -r s -r / -r F -r o -r l -r d -r e -r r -r C -r h -r i -r l -r d -r r -r e -r n -r . -r j -r a -r v -r a openide.loaders/src/org/openide/loaders/FolderChildren.java
--- a/openide.loaders/src/org/openide/loaders/FolderChildren.java
+++ b/openide.loaders/src/org/openide/loaders/FolderChildren.java
@@ -47,35 +47,31 @@ import java.util.logging.Level;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.event.*;
+import org.openide.filesystems.FileAttributeEvent;
+import org.openide.filesystems.FileChangeListener;
+import org.openide.filesystems.FileEvent;
import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileRenameEvent;
import org.openide.nodes.*;
-import org.openide.util.RequestProcessor;
/** Watches over a folder and represents its
* child data objects by nodes.
*
* @author Jaroslav Tulach
*/
-final class FolderChildren extends Children.Keys<FolderChildren.Pair>
-implements PropertyChangeListener, ChangeListener {
+final class FolderChildren extends Children.Keys<FileObject>
+ implements PropertyChangeListener, ChangeListener, FileChangeListener {
+
/** the folder */
private DataFolder folder;
/** filter of objects */
private final DataFilter filter;
/** listener on changes in nodes */
private PropertyChangeListener listener;
+ /** file change listener */
+ private FileChangeListener fcListener;
/** logging, if needed */
private Logger err;
- /** true if the refrersh is done after DataFilter change */
- private boolean refresh;
- /** we wait for this task finished in getNodes(true) */
- private RequestProcessor.Task refreshTask;
- /** Runnable scheduled to refRP */
- private ChildrenRefreshRunnable refreshRunnable;
-
- /** Private req processor for the refresh tasks */
- private static RequestProcessor refRP =
- new RequestProcessor("FolderChildren_Refresh"); // NOI18N
/**
* @param f folder to display content of
@@ -90,11 +86,11 @@ implements PropertyChangeListener, Chang
* @param filter filter of objects
*/
public FolderChildren(DataFolder f, DataFilter filter) {
+ super(true);
this.folder = f;
this.filter = filter;
- this.refreshRunnable = new ChildrenRefreshRunnable();
- this.refreshTask = refRP.create(refreshRunnable);
this.listener = org.openide.util.WeakListeners.propertyChange(this, folder);
+ this.fcListener = org.openide.filesystems.FileUtil.weakFileChangeListener(this, folder.getPrimaryFile());
String log;
if (f.getPrimaryFile().isRoot()) {
log = "org.openide.loaders.FolderChildren"; // NOI18N
@@ -110,58 +106,51 @@ implements PropertyChangeListener, Chang
}
/** If the folder changed its children we change our nodes.
- */
- public void propertyChange (final PropertyChangeEvent ev) {
- if (DataFolder.PROP_CHILDREN.equals (ev.getPropertyName ())) {
+ */
+ public void propertyChange(final PropertyChangeEvent ev) {
+ if (DataFolder.PROP_CHILDREN.equals(ev.getPropertyName())) {
err.fine("Got PROP_CHILDREN");
- refreshChildren().schedule (0);
- postClearTask();
+ refreshChildren(false);
return;
}
- if (
- DataFolder.PROP_SORT_MODE.equals (ev.getPropertyName ()) ||
- DataFolder.PROP_ORDER.equals (ev.getPropertyName ())
- ) {
+ if (DataFolder.PROP_SORT_MODE.equals(ev.getPropertyName()) ||
+ DataFolder.PROP_ORDER.equals(ev.getPropertyName())) {
err.fine("Got PROP_SORT_MODE or PROP_ORDER");
- refreshChildren().schedule (0);
- postClearTask();
- return;
+ refreshChildren(false);
}
}
- public void stateChanged( ChangeEvent e ) {
+ public void stateChanged(ChangeEvent e) {
// Filtering changed need to recompute children
- refresh = true;
- refreshChildren().schedule(0);
- postClearTask();
- return;
- }
-
- /**
- * refreshRunnable holds references to the data object
- * to prevent GC. This method post a task to the same request processor
- * (refRP) to clear this references after they are no longer needed.
- */
- private void postClearTask() {
- refRP.post(new Runnable() {
- public void run() {
- refreshRunnable.clear();
- }
- });
+ refreshChildren(true);
}
- /** Refreshes the children.
- */
- RequestProcessor.Task refreshChildren() {
- return refreshTask;
+ /** Deep refresh or not. */
+ final void refreshChildren(boolean deep) {
+ final FileObject[] arr = folder.getPrimaryFile().getChildren();
+ FolderOrder order = FolderOrder.findFor(folder.getPrimaryFile());
+ Arrays.sort(arr, order);
+
+ if (deep) {
+ MUTEX.postWriteRequest(new Runnable() {
+
+ public void run() {
+ List<FileObject> emptyList = Collections.emptyList();
+ setKeys(emptyList);
+ setKeys(arr);
+ }
+ });
+ return;
+ } else {
+ setKeys(arr);
+ }
}
/** Create a node for one data object.
* @param key DataObject
*/
- protected Node[] createNodes(Pair key) {
- err.fine("createNodes: " + key);
- FileObject fo = key.primaryFile;
+ protected Node[] createNodes(FileObject fo) {
+ err.fine("createNodes: " + fo);
DataObject obj;
try {
obj = DataObject.find (fo);
@@ -176,41 +165,47 @@ implements PropertyChangeListener, Chang
}
}
+ @Override
public Node[] getNodes(boolean optimalResult) {
- Node[] res;
- Object hold;
-
if (optimalResult) {
if (checkChildrenMutex()) {
err.fine("getNodes(true)"); // NOI18N
FolderList.find(folder.getPrimaryFile(), true).waitProcessingFinished();
err.fine("getNodes(true): waitProcessingFinished"); // NOI18N
- RequestProcessor.Task task = refreshChildren();
- res = getNodes();
- err.fine("getNodes(true): getNodes: " + res.length); // NOI18N
- task.schedule(0);
- task.waitFinished();
- err.fine("getNodes(true): waitFinished"); // NOI18N
+ //refreshChildren(false);
} else {
Logger.getLogger(FolderChildren.class.getName()).log(Level.WARNING, null,
new java.lang.IllegalStateException("getNodes(true) called while holding the Children.MUTEX"));
}
}
- res = getNodes();
- err.fine("getNodes(boolean): post clear task"); // NOI18N
- postClearTask(); // we can clean the references to data objects now
- // they are no longer needed
+ Node[] res = getNodes();
return res;
}
+ @Override
public Node findChild(String name) {
if (checkChildrenMutex()) {
- getNodes(true);
+ getNodesCount(true);
}
return super.findChild(name);
}
-
+ @Override
+ public int getNodesCount(boolean optimalResult) {
+ if (optimalResult) {
+ if (checkChildrenMutex()) {
+ err.fine("getNodesCount(true)"); // NOI18N
+ FolderList.find(folder.getPrimaryFile(), true).waitProcessingFinished();
+ err.fine("getNodesCount(true): waitProcessingFinished"); // NOI18N
+ //refreshChildren(false);
+ } else {
+ Logger.getLogger(FolderChildren.class.getName()).log(Level.WARNING, null,
+ new java.lang.IllegalStateException("getNodes(true) called while holding the Children.MUTEX"));
+ }
+ }
+ int count = getNodesCount();
+ return count;
+ }
/**
* @return true if it is safe to wait (our thread is
@@ -222,120 +217,69 @@ implements PropertyChangeListener, Chang
/** Initializes the children.
*/
+ @Override
protected void addNotify () {
err.fine("addNotify begin");
// add as a listener for changes on nodes
- folder.addPropertyChangeListener (listener);
+ folder.addPropertyChangeListener(listener);
+ folder.getPrimaryFile().addFileChangeListener(fcListener);
// add listener to the filter
if ( filter instanceof ChangeableDataFilter ) {
((ChangeableDataFilter)filter).addChangeListener( this );
}
// start the refresh task to compute the children
- refreshChildren().schedule(0);
+ refreshChildren(false);
err.fine("addNotify end");
}
/** Deinitializes the children.
*/
+ @Override
protected void removeNotify () {
err.fine("removeNotify begin");
- // removes the listener
- folder.removePropertyChangeListener (listener);
+ // removes the listeners
+ folder.getPrimaryFile().removeFileChangeListener(fcListener);
+ folder.removePropertyChangeListener(listener);
// remove listener from filter
if ( filter instanceof ChangeableDataFilter ) {
((ChangeableDataFilter)filter).removeChangeListener( this );
}
// we need to clear the children now
- setKeys(Collections.<Pair>emptySet());
+ List<FileObject> emptyList = Collections.emptyList();
+ setKeys(emptyList);
err.fine("removeNotify end");
}
/** Display name */
+ @Override
public String toString () {
return (folder != null) ? folder.getPrimaryFile ().toString () : super.toString();
}
-
- /**
- * Instances of this class are posted to the request processor refRP
- * (FolderChildren_refresher). We do this because we do not want
- * to call setKeys synchronously.
- */
- private final class ChildrenRefreshRunnable implements Runnable {
- /** store the referneces to the data objects to
- * prevent GC.
- */
- private DataObject[] ch;
-
- /** calls setKeys with the folder children
- * or with empty collection if active is false
- */
- public void run() {
- // this can be run only on the refRP thread
- assert refRP.isRequestProcessorThread();
- FolderList.find(folder.getPrimaryFile(), true).waitProcessingFinished();
-
- ch = folder.getChildren();
- err.fine("Children computed");
- Pair[] keys = new Pair[ch.length];
- for (int i = 0; i < keys.length; i++) {
- keys[i] = new Pair(ch[i].getPrimaryFile());
- }
- setKeys(Arrays.asList(keys));
-
- if ( refresh ) {
- refresh = false;
- for (Pair key : keys) {
- refreshKey(key);
- }
- }
-
- if (!isInitialized()) {
- clear();
- }
- }
-
- /** stop holding the references to the data objects. After
- * calling this they can be GCed again.
- */
- public void clear() {
- // this can be run only on the refRP thread
- assert refRP.isRequestProcessorThread();
- err.fine("Clearing the reference to children"); // NOI18N
- ch = null;
+ public void fileAttributeChanged(FileAttributeEvent fe) {
+ if (DataObject.EA_ASSIGNED_LOADER.equals(fe.getName())) {
+ // make sure this event is processed by the data system
+ DataObjectPool.checkAttributeChanged(fe);
+ refreshKey(fe.getFile());
}
}
-
- /** Pair of dataobject invalidation sequence # and primary file.
- * It serves as a key for the given data object.
- * It is here to create something different then data object,
- * because the data object should be finalized when not needed and
- * that is why it should not be used as a key.
- */
- static final class Pair extends Object {
- public FileObject primaryFile;
- public int seq;
- public Pair (FileObject primaryFile) {
- this.primaryFile = primaryFile;
- this.seq = DataObjectPool.getPOOL().registrationCount(primaryFile);
- }
+ public void fileChanged(FileEvent fe) {
+ }
- public int hashCode () {
- return primaryFile.hashCode () ^ seq;
- }
+ public void fileDataCreated(FileEvent fe) {
+ refreshChildren(false);
+ }
- public boolean equals (Object o) {
- if (o instanceof Pair) {
- Pair p = (Pair)o;
- return primaryFile.equals (p.primaryFile) && seq == p.seq;
- }
- return false;
- }
-
- public String toString() {
- return "FolderChildren.Pair[" + primaryFile + "," + seq + "]"; // NOI18N
- }
+ public void fileDeleted(FileEvent fe) {
+ refreshChildren(false);
+ }
+
+ public void fileFolderCreated(FileEvent fe) {
+ refreshChildren(false);
+ }
+
+ public void fileRenamed(FileRenameEvent fe) {
}
}
diff -r o -r p -r e -r n -r i -r d -r e -r . -r l -r o -r a -r d -r e -r r -r s -r / -r s -r r -r c -r / -r o -r r -r g -r / -r o -r p -r e -r n -r i -r d -r e -r / -r l -r o -r a -r d -r e -r r -r s -r / -r F -r o -r l -r d -r e -r r -r C -r o -r m -r p -r a -r r -r a -r t -r o -r r -r . -r j -r a -r v -r a openide.loaders/src/org/openide/loaders/FolderComparator.java
--- a/openide.loaders/src/org/openide/loaders/FolderComparator.java
+++ b/openide.loaders/src/org/openide/loaders/FolderComparator.java
@@ -41,9 +41,11 @@
package org.openide.loaders;
+import java.util.Comparator;
import java.util.Date;
import java.util.Enumeration;
import org.openide.filesystems.FileObject;
+import org.openide.nodes.Node;
/**
* Compares objects in a folder.
@@ -80,10 +82,14 @@ class FolderComparator extends DataFolde
this.mode = mode;
}
+ public int compare(DataObject o1, DataObject o2) {
+ return doCompare((Object) o1, (Object) o2);
+ }
+
/** Comparing method. Can compare two DataObjects
- * or two Nodes (if they have data object cookie)
+ * or two Nodes (if they have data object cookie) or two FileObjects
*/
- public int compare(DataObject obj1, DataObject obj2) {
+ int doCompare(Object obj1, Object obj2) {
switch (mode) {
case NONE:
return 0;
@@ -103,34 +109,57 @@ class FolderComparator extends DataFolde
}
}
+ static FileObject findFileObject(Object o) {
+ if (o instanceof FileObject) {
+ return (FileObject) o;
+ }
+ if (o instanceof DataObject) {
+ return ((DataObject) o).getPrimaryFile();
+ }
+ Node n = (Node) o;
+ DataObject obj = (DataObject) n.getCookie(DataObject.class);
+ return obj.getPrimaryFile();
+ }
+
+ private static DataObject findDataObject(Object o) {
+ if (o instanceof DataObject) {
+ return (DataObject) o;
+ }
+ if (o instanceof FileObject) {
+ try {
+ return DataObject.find((FileObject) o);
+ } catch (DataObjectNotFoundException ex) {
+ return null;
+ }
+ }
+ Node n = (Node) o;
+ DataObject obj = (DataObject) n.getCookie(DataObject.class);
+ return obj;
+ }
/** for sorting data objects by names */
- private int compareNames (DataObject obj1, DataObject obj2) {
- // #35069 - use extension for sorting if displayname is same.
- // Otherwise the order of files is random.
- int part = obj1.getName().compareTo(obj2.getName());
- return part != 0 ? part :
- obj1.getPrimaryFile().getExt().compareTo(obj2.getPrimaryFile().getExt());
+ private int compareNames(Object o1, Object o2) {
+ return findFileObject(o1).getNameExt().compareTo(findFileObject(o2).getNameExt());
}
/** for sorting folders first and then by names */
- private int compareFoldersFirst (DataObject obj1, DataObject obj2) {
- if (obj1.getClass () != obj2.getClass ()) {
- // if classes are different than the folder goes first
- if (obj1 instanceof DataFolder) {
- return -1;
- }
- if (obj2 instanceof DataFolder) {
- return 1;
- }
+ private int compareFoldersFirst(Object o1, Object o2) {
+ boolean f1 = findFileObject(o1).isFolder();
+ boolean f2 = findFileObject(o2).isFolder();
+
+ if (f1 != f2) {
+ return f1 ? -1 : 1;
}
// otherwise compare by names
- return compareNames(obj1, obj2);
+ return compareNames(o1, o2);
}
/** for sorting data objects by their classes */
- private int compareClass (DataObject obj1, DataObject obj2) {
+ private int compareClass(Object o1, Object o2) {
+ DataObject obj1 = findDataObject(o1);
+ DataObject obj2 = findDataObject(o2);
+
Class<?> c1 = obj1.getClass ();
Class<?> c2 = obj2.getClass ();
@@ -165,59 +194,48 @@ class FolderComparator extends DataFolde
/**
* Sort folders alphabetically first. Then files, newest to oldest.
*/
- private static int compareLastModified(DataObject obj1, DataObject obj2) {
- if (obj1 instanceof DataFolder) {
- if (obj2 instanceof DataFolder) {
- return obj1.getName().compareTo(obj2.getName());
- } else {
- return -1;
- }
+ private static int compareLastModified(Object o1, Object o2) {
+ boolean f1 = findFileObject(o1).isFolder();
+ boolean f2 = findFileObject(o2).isFolder();
+
+ if (f1 != f2) {
+ return f1 ? -1 : 1;
+ }
+
+ FileObject fo1 = findFileObject(o1);
+ FileObject fo2 = findFileObject(o2);
+ Date d1 = fo1.lastModified();
+ Date d2 = fo2.lastModified();
+ if (d1.after(d2)) {
+ return -1;
+ } else if (d2.after(d1)) {
+ return 1;
} else {
- if (obj2 instanceof DataFolder) {
- return 1;
- } else {
- FileObject fo1 = obj1.getPrimaryFile();
- FileObject fo2 = obj2.getPrimaryFile();
- Date d1 = fo1.lastModified();
- Date d2 = fo2.lastModified();
- if (d1.after(d2)) {
- return -1;
- } else if (d2.after(d1)) {
- return 1;
- } else {
- return fo1.getNameExt().compareTo(fo2.getNameExt());
- }
- }
+ return fo1.getNameExt().compareTo(fo2.getNameExt());
}
}
/**
* Sort folders alphabetically first. Then files, biggest to smallest.
*/
- private static int compareSize(DataObject obj1, DataObject obj2) {
- if (obj1 instanceof DataFolder) {
- if (obj2 instanceof DataFolder) {
- return obj1.getName().compareTo(obj2.getName());
- } else {
- return -1;
- }
+ private static int compareSize(Object o1, Object o2) {
+ boolean f1 = findFileObject(o1).isFolder();
+ boolean f2 = findFileObject(o2).isFolder();
+
+ if (f1 != f2) {
+ return f1 ? -1 : 1;
+ }
+
+ FileObject fo1 = findFileObject(o1);
+ FileObject fo2 = findFileObject(o2);
+ long s1 = fo1.getSize();
+ long s2 = fo2.getSize();
+ if (s1 > s2) {
+ return -1;
+ } else if (s2 > s1) {
+ return 1;
} else {
- if (obj2 instanceof DataFolder) {
- return 1;
- } else {
- FileObject fo1 = obj1.getPrimaryFile();
- FileObject fo2 = obj2.getPrimaryFile();
- long s1 = fo1.getSize();
- long s2 = fo2.getSize();
- if (s1 > s2) {
- return -1;
- } else if (s2 > s1) {
- return 1;
- } else {
- return fo1.getNameExt().compareTo(fo2.getNameExt());
- }
- }
+ return fo1.getNameExt().compareTo(fo2.getNameExt());
}
}
-
}
diff -r o -r p -r e -r n -r i -r d -r e -r . -r l -r o -r a -r d -r e -r r -r s -r / -r s -r r -r c -r / -r o -r r -r g -r / -r o -r p -r e -r n -r i -r d -r e -r / -r l -r o -r a -r d -r e -r r -r s -r / -r F -r o -r l -r d -r e -r r -r O -r r -r d -r e -r r -r . -r j -r a -r v -r a openide.loaders/src/org/openide/loaders/FolderOrder.java
--- a/openide.loaders/src/org/openide/loaders/FolderOrder.java
+++ b/openide.loaders/src/org/openide/loaders/FolderOrder.java
@@ -55,7 +55,7 @@ import org.openide.loaders.DataFolder.So
*
* @author Jaroslav Tulach
*/
-final class FolderOrder extends Object implements Comparator<DataObject> {
+final class FolderOrder extends Object implements Comparator<Object> {
/** a static map with (FileObject, Reference (Folder))
*/
@@ -142,15 +142,15 @@ final class FolderOrder extends Object i
/** Compares two data object or two nodes.
*/
- public int compare (DataObject obj1, DataObject obj2) {
- Integer i1 = (order == null) ? null : order.get (obj1.getPrimaryFile ().getNameExt ());
- Integer i2 = (order == null) ? null : order.get (obj2.getPrimaryFile ().getNameExt ());
+ public int compare (Object obj1, Object obj2) {
+ Integer i1 = (order == null) ? null : (Integer) order.get(FolderComparator.findFileObject(obj1).getNameExt());
+ Integer i2 = (order == null) ? null : (Integer) order.get(FolderComparator.findFileObject(obj2).getNameExt());
if (i1 == null) {
if (i2 != null) return 1;
// compare by the provided comparator
- return getSortMode ().compare (obj1, obj2);
+ return ((FolderComparator)(getSortMode())).doCompare(obj1, obj2);
} else {
if (i2 == null) return -1;
// compare integers
diff -r o -r p -r e -r n -r i -r d -r e -r . -r n -r o -r d -r e -r s -r / -r s -r r -r c -r / -r o -r r -r g -r / -r o -r p -r e -r n -r i -r d -r e -r / -r n -r o -r d -r e -r s -r / -r C -r h -r i -r l -r d -r r -r e -r n -r . -r j -r a -r v -r a openide.nodes/src/org/openide/nodes/Children.java
--- a/openide.nodes/src/org/openide/nodes/Children.java
+++ b/openide.nodes/src/org/openide/nodes/Children.java
@@ -123,6 +123,11 @@ public abstract class Children extends O
/** Constructor.
*/
public Children() {
+ this(false);
+ }
+
+ public Children(boolean lazy) {
+ lazySupport = lazy;
}
/**
@@ -137,13 +142,15 @@ public abstract class Children extends O
return entrySupport;
}
}
-
+
+ final boolean lazySupport;
/**
* Creates appropriate entry support for this children.
* Overriden in Children.Keys to sometimes make lazy support.
*/
EntrySupport createEntrySource() {
- return new EntrySupport.Default(this);
+ return lazySupport ? new EntrySupport.Lazy(this) : new EntrySupport.Default(this);
+ //return new EntrySupport.Lazy(this);
}
/**
@@ -310,6 +317,7 @@ public abstract class Children extends O
* a parent node
* *exception CloneNotSupportedException if <code>Cloneable</code> interface is not implemented
*/
+ @Override
protected Object clone() throws CloneNotSupportedException {
Children ch = (Children) super.clone();
ch.parent = null;
@@ -452,7 +460,14 @@ public abstract class Children extends O
* @return the count
*/
public final int getNodesCount() {
- return entrySupport().getNodesCount();
+ return entrySupport().getNodesCount(false);
+ }
+
+ /** Get the number of nodes in the list
+ * @return the count
+ */
+ public int getNodesCount(boolean optimalResult) {
+ return entrySupport().getNodesCount(optimalResult);
}
//
@@ -485,7 +500,21 @@ public abstract class Children extends O
* do additional work and then call addNotify.
*/
void callAddNotify() {
+ //System.err.println("Thread: " + Thread.currentThread().getName() + ", N: " + getNode());
+ //System.err.println("Children: " + this);
addNotify();
+ //System.err.println("Finished: " + this);
+ }
+
+ /** Called when the nodes have been removed from the children.
+ * This method should allow subclasses to clean the nodes somehow.
+ * <p>
+ * Current implementation notifies all listeners on the nodes
+ * that nodes have been deleted.
+ *
+ * @param arr array of deleted nodes
+ */
+ void destroyNodes(Node[] arr) {
}
/** @return either nodes associated with this children or null if
@@ -495,68 +524,6 @@ public abstract class Children extends O
return entrySupport == null ? null : entrySupport().testNodes();
}
- /** Notifies that a set of nodes has been removed from
- * children. It is necessary that the system is already
- * in consistent state, so any callbacks will return
- * valid values.
- *
- * @param nodes list of removed nodes
- * @param current state of nodes
- * @return array of nodes that were deleted
- */
- Node[] notifyRemove(Collection<Node> nodes, Node[] current) {
- //System.err.println("notifyRemove from: " + getNode ());
- //System.err.println("notifyRemove: " + nodes);
- //System.err.println("Current : " + Arrays.asList (current));
- //Thread.dumpStack();
- //Keys.last.printStackTrace();
- // [TODO] Children do not have always a parent
- // see Services->FIRST ($SubLevel.class)
- // during a deserialization it may have parent == null
- Node[] arr = nodes.toArray(new Node[nodes.size()]);
-
- if (parent == null) {
- return arr;
- }
-
- // fire change of nodes
- parent.fireSubNodesChange(false, // remove
- arr, current);
-
- // fire change of parent
- Iterator it = nodes.iterator();
-
- while (it.hasNext()) {
- Node n = (Node) it.next();
- n.deassignFrom(this);
- n.fireParentNodeChange(parent, null);
- }
-
- return arr;
- }
-
- /** Notifies that a set of nodes has been add to
- * children. It is necessary that the system is already
- * in consistent state, so any callbacks will return
- * valid values.
- *
- * @param nodes list of removed nodes
- */
- void notifyAdd(Collection<Node> nodes) {
- // notify about parent change
- for (Node n : nodes) {
- n.assignTo(this, -1);
- n.fireParentNodeChange(null, parent);
- }
-
- Node[] arr = nodes.toArray(new Node[nodes.size()]);
-
- Node n = parent;
-
- if (n != null) {
- n.fireSubNodesChange(true, arr, null);
- }
- }
/** Interface that provides a set of nodes.
*/
@@ -622,8 +589,15 @@ public abstract class Children extends O
* first time, children will be used.
*/
public Array() {
- nodesEntry = createNodesEntry();
- entrySupport().setEntries(Collections.singleton(getNodesEntry()));
+ this(false);
+ }
+
+ Array(boolean lazy) {
+ super(lazy);
+ if (!lazy) {
+ nodesEntry = createNodesEntry();
+ entrySupport().setEntries(Collections.singleton(getNodesEntry()));
+ }
}
/** Clones all nodes that are contained in the children list.
@@ -741,12 +715,8 @@ public abstract class Children extends O
// no change to the collection
return false;
}
-
- ;
}
-
refresh();
-
return true;
}
@@ -1020,12 +990,14 @@ public abstract class Children extends O
/** Hash code.
*/
+ @Override
public int hashCode() {
return key.hashCode();
}
/** Equals.
*/
+ @Override
public boolean equals(Object o) {
if (o instanceof ME) {
ME me = (ME) o;
@@ -1036,6 +1008,7 @@ public abstract class Children extends O
return false;
}
+ @Override
public String toString() {
return "Key (" + key + ")"; // NOI18N
}
@@ -1090,6 +1063,7 @@ public abstract class Children extends O
/** This method allows subclasses (only in this package) to
* provide own version of entry. Useful for SortedArray.
*/
+ @Override
Entry createNodesEntry() {
return new SAE();
}
@@ -1164,6 +1138,7 @@ public abstract class Children extends O
* @param map the map (Object, Node)
* @return collection of (Entry)
*/
+ @Override
Collection<? extends Entry> createEn