Hi all i try to expand programmatically the node of a JTreeTable but it not works,is my own JTreetable but i try with the Swing Tutorial example too and
i'm not able to do this.
I try
TreePath tp = new TreePath(dtm.getPath());
tree.expandPath(tp);
where dtm is DefaultMutableTreeNode.
I think the problem is on my model
public class GenericModel extends AbstractTreeTableModel {
protected String[] cNames;
protected int[] cWidths;
protected Class[] cTypes;
protected boolean[] editable;
/** Returns true if links are to be descended. */
protected boolean descendLinks;
public GenericModel(DefaultMutableTreeNode defaultMutableTreeNode,
String[] colNames, int[] colWidths, Class[] cl) {
super(null);
this.cNames = colNames;
this.cWidths = colWidths;
cTypes = new Class[colNames.length];
cTypes[0] = TreeTableModel.class;
editable = new boolean[colNames.length];
for (int i = 1; i < cTypes.length; i++) {
cTypes[i] = cl[i - 1];
editable[i] = false;
}
root = new GenericNode(null, defaultMutableTreeNode);
}
public GenericModel(DefaultMutableTreeNode defaultMutableTreeNode,
String[] colNames, int[] colWidths, Class[] cl, boolean[] editable) {
this(defaultMutableTreeNode, colNames, colWidths, cl);
this.editable = editable;
}
/**
* Returns the number of children of <code>node</code>.
*/
public int getChildCount(Object node) {
Object[] children = getChildren(node);
return (children == null) ? 0 : children.length;
}
/**
* Returns the child of <code>node</code> at index <code>i</code>.
*/
public Object getChild(Object node, int i) {
return getChildren(node);
}
/**
* Returns true if the passed in object represents a leaf, false otherwise.
*/
public boolean isLeaf(Object node) {
// Controllo perchè se ad esempio sto espandendo i nodi potrebbe
// arrivarmi un DefaultMutableTreeNode
if (node instanceof DefaultMutableTreeNode) {
return ((DefaultMutableTreeNode) node).isLeaf();
}
return ((GenericNode) node).isLeaf();
}
/**
* Returns the number of columns.
*/
public int getColumnCount() {
return cNames.length;
}
/**
* Returns the name for a particular column.
*/
public String getColumnName(int column) {
return cNames[column];
}
/**
* Returns the class for the particular column.
*/
public Class getColumnClass(int column) {
return cTypes[column];
}
/**
* Returns the value of the particular column.
*/
public Object getValueAt(Object node, int column) {
GenericNode genericNode = (GenericNode) node;
try {
Object vo = genericNode.getDefaultMutableTreeNode().getUserObject();
if (vo instanceof RowRootVO) {
RowRootVO rowRootVO = (RowRootVO) vo;
try {
if (column <= rowRootVO.getDescription().size() - 1)
return rowRootVO.getDescription().get(column);
} catch (RuntimeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else if (vo instanceof RowVO) {
RowVO rowVO = (RowVO) vo;
if (column <= rowVO.getColumnData().size() - 1)
// return ((TreeTag) rowVO.get(column)).getData();
return Converter.fieldFormatter(Converter.objectFormatter(
((TreeTag) rowVO.get(column)).getData(),
((TreeTag) rowVO.get(column)).getDataType()),
((TreeTag) rowVO.get(column)).getDataType());
}
} catch (ObjectFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* Reloads the children of the specified node.
*/
public void reloadChildren(Object node) {
GenericNode genericNode = (GenericNode) node;
// genericNode.resetSize();
GenericNodeLoader genericNodeLoader = new GenericNodeLoader(genericNode);
Thread thread = new Thread(genericNodeLoader);
thread.start();
}
/**
* Stops and waits for all threads to finish loading.
*/
/*
* public void stopLoading() { isValid = false;
*
* synchronized (this) { while (reloadCount > 0) { try { wait(); } catch
* (InterruptedException ie) { } } }
*
* isValid = true; }
*/
/**
* If <code>newValue</code> is true, links are descended. Odd results may
* happen if you set this while other threads are loading.
*/
public void setDescendsLinks(boolean descendLinks) {
this.descendLinks = descendLinks;
}
/**
* Returns true if links are to be automatically descended.
*/
public boolean getDescendsLinks() {
return descendLinks;
}
protected Object[] getChildren(Object node) {
GenericNode genericNode = ((GenericNode) node);
return genericNode.getChildren();
}
public class GenericNode {
/** Parent FileNode of the receiver. */
private GenericNode parentGenericNode;
/** Children of the receiver. */
protected GenericNode[] children;
/**
* True if the canonicalPath of this instance does not start with the
* canonical path of the parent.
*/
protected boolean isLink;
/** Date last modified. */
protected DefaultMutableTreeNode defaultMutableTreeNode;
protected GenericNode(GenericNode parentNode,
DefaultMutableTreeNode defaultMutableTreeNode) {
this.parentGenericNode = parentNode;
this.defaultMutableTreeNode = defaultMutableTreeNode;
}
public DefaultMutableTreeNode getDefaultMutableTreeNode() {
return this.defaultMutableTreeNode;
}
public String toString() {
try {
Object vo = this.defaultMutableTreeNode.getUserObject();
if (vo instanceof RowRootVO) {
RowRootVO rowRootVO = (RowRootVO) vo;
return rowRootVO.getDescription().get(0);
} else if (vo instanceof RowVO) {
RowVO rowVO = (RowVO) vo;
return Converter.fieldFormatter(Converter.objectFormatter(
((TreeTag) rowVO.get(0)).getData(),
((TreeTag) rowVO.get(0)).getDataType()),
((TreeTag) rowVO.get(0)).getDataType());
}
} catch (ObjectFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public GenericNode getParent() {
return parentGenericNode;
}
/**
* Returns true if the receiver represents a leaf, that is it is isn't a
* directory.
*/
public boolean isLeaf() {
// return file.isFile();
return this.defaultMutableTreeNode.isLeaf();
}
protected GenericNode[] getChildren() {
return children;
}
protected void loadChildren() {
this.children = createChildren();
for (int counter = children.length - 1; counter >= 0; counter--) {
Thread.yield(); // Give the GUI CPU time to draw itself.
if (!children[counter].isLeaf()
&& (descendLinks || !children[counter].isLink())) {
children[counter].loadChildren();
}
}
}
protected GenericNode[] createChildren() {
GenericNode[] children = new GenericNode[this.defaultMutableTreeNode
.getChildCount()];
DefaultMutableTreeNode child;
for (int i = 0; i < this.defaultMutableTreeNode.getChildCount(); i++) {
child = (DefaultMutableTreeNode) this.defaultMutableTreeNode
.getChildAt(i);
children[i] = new GenericNode(this, child);
}
return children;
}
/**
* Gets the path from the root to the receiver.
*/
public GenericNode[] getPath() {
return getPathToRoot(this, 0);
}
/**
* Returns true if the receiver's path does not begin with the parent's
* canonical path.
*/
public boolean isLink() {
return isLink;
}
protected GenericNode[] getPathToRoot(GenericNode genericNode, int depth) {
GenericNode[] retNodes;
if (genericNode == null) {
if (depth == 0) {
return null;
} else {
retNodes = new GenericNode[depth];
}
} else {
depth++;
retNodes = getPathToRoot(genericNode.getParent(), depth);
retNodes[retNodes.length - depth] = genericNode;
}
return retNodes;
}
/**
* Sets the children of the receiver, updates the total size, and if
* generateEvent is true a tree structure changed event is created.
*/
protected void setChildren(GenericNode[] children, boolean generateEvent) {
// long oldSize = totalSize;
// totalSize = file.length();
this.children = children;
/*
* for (int counter = children.length - 1; counter >= 0; counter--) {
* totalSize += children[counter].totalSize(); }
*/
if (generateEvent) {
GenericNode[] path = getPath();
fireTreeStructureChanged(GenericModel.this, path, null, null);
/*
* GenericNode parent = getParent();
*
* if (parent != null) { parent.alterTotalSize(totalSize -
* oldSize); }
*/
}
}
}
class GenericNodeLoader implements Runnable {
/** Node creating children for. */
GenericNode genericNode;
GenericNodeLoader(GenericNode genericNode) {
this.genericNode = genericNode;
this.genericNode.setChildren(this.genericNode.createChildren(),
true);
}
public void run() {
GenericNode[] children = genericNode.getChildren();
for (int counter = children.length - 1; counter >= 0; counter--) {
if (!children[counter].isLeaf()) {
final GenericNode genericChild = children[counter];
SwingUtilities.invokeLater(new Runnable() {
public void run() {
reloadChildren(genericChild);
}
});
}
}
}
protected void loadChildren(GenericNode genericNode) {
if (!genericNode.isLeaf()
&& (descendLinks || !genericNode.isLink())) {
final GenericNode[] children = genericNode.createChildren();
for (int counter = children.length - 1; counter >= 0; counter--) {
if (!children[counter].isLeaf()) {
children[counter].loadChildren();
}
}
} else {
}
}
}
public int[] getCWidths() {
return cWidths;
}
public void setCWidths(int[] widths) {
cWidths = widths;
}
public boolean[] getEditable() {
return editable;
}
public void setEditable(boolean[] editable) {
this.editable = editable;
}
public void valueForPathChanged(TreePath path, Object newValue) {
// TODO Auto-generated method stub
}
@Override
public void setValueAt(Object aValue, Object node, int column) {
// TODO Auto-generated method stub
GenericNode parent = ((GenericNode) node);
Object vo = parent.getDefaultMutableTreeNode().getUserObject();
if (vo instanceof RowRootVO) {
// RowRootVO rowRootVO = (RowRootVO) vo;
// rowRootVO.getDescription().get(column);
} else if (vo instanceof RowVO) {
RowVO rowVO = (RowVO) vo;
rowVO.set(aValue, column);
}
fireTreeNodesChanged(this, getPathToRoot(parent),
new int[] { getIndexOfChild(parent, node) },
new Object[] { node });
}
/**
* Builds the parents of the node up to and including the root node, where
* the original node is the last element in the returned array. The length
* of the returned array gives the node's depth in the tree.
*
* @param aNode
* the TreeNode to get the path for
* @param an
* array of TreeNodes giving the path from the root to the
* specified node.
*/
public GenericNode[] getPathToRoot(GenericNode aNode) {
return getPathToRoot(aNode, 0);
}
/**
* Builds the parents of the node up to and including the root node, where
* the original node is the last element in the returned array. The length
* of the returned array gives the node's depth in the tree.
*
* @param aNode
* the TreeNode to get the path for
* @param depth
* an int giving the number of steps already taken towards the
* root (on recursive calls), used to size the returned array
* @return an array of TreeNodes giving the path from the root to the
* specified node
*/
private GenericNode[] getPathToRoot(GenericNode aNode, int depth) {
GenericNode[] retNodes;
// This method recurses, traversing towards the root in order
// size the array. On the way back, it fills in the nodes,
// starting from the root and working back to the original node.
/*
* Check for null, in case someone passed in a null node, or they passed
* in an element that isn't rooted at root.
*/
if (aNode == null) {
if (depth == 0)
return null;
else
retNodes = new GenericNode[depth];
} else {
depth++;
if (aNode == root)
retNodes = new GenericNode[depth];
else
retNodes = getPathToRoot(aNode.getParent(), depth);
retNodes[retNodes.length - depth] = aNode;
}
return retNodes;
}
/**
* Sorts the contents, which must be instances of FileNode based on
* totalSize.
*/
/*
* static class SizeSorter extends MergeSort { public int
* compareElementsAt(int beginLoc, int endLoc) { long firstSize =
* ((GenericNode) toSort[beginLoc]).totalSize(); long secondSize =
* ((GenericNode) toSort[endLoc]).totalSize();
*
* if (firstSize != secondSize) { return (int) (secondSize - firstSize); }
*
* return ((GenericNode)
* toSort[beginLoc]).toString().compareTo(((GenericNode)
* toSort[endLoc]).toString()); } }
*/
}
Any idea?