Article View: borland.public.jbuilder.java.swing
Article #1528Re: displaying child nodes on demand
From: Alan Shiers
Date: Mon, 27 Oct 2003 00:14
Date: Mon, 27 Oct 2003 00:14
287 lines
10629 bytes
10629 bytes
Hi there,
Ok, I've done a little more digging. I finally realized that subclassing
DefaultTreeModel is what would give me access to the
fireTreeStructureChanged() method. So I did exactly that. Below you'll
find my entire class. The ReceiveChildrenFromServer( ) method is the one
I'm having a challenge with.
In the class that contains the JTree I listen for tree expansion events, so
in the treeWillExpand( ) method I set a boolean flag in MyTreeModel and the
path to the node that was expanded, like so:
public void treeWillExpand(javax.swing.event.TreeExpansionEvent tee) throws
javax.swing.tree.ExpandVetoException
{
System.out.println("Node Expanding.");
model.setNodeExpanding(true);
model.setParentNodesPath(tee.getPath());
expandingNode = (DefaultTreeNode)tee.getPath().getLastPathComponent();
}
Everytime the getChildCount() method in MyTreeModel is called it sends a
request to the server for the childCount, also if the flag NodeExpanding is
set to true (which it would be from the treeWillExpand( ) method), then we
call RequestChildrenFromServer( ) method which in turn calls
ReceiveChildrenFromServer( ) method.
The ReceiveChildrenFromServer( ) method is definitely collecting the names
of each node as it is being transmitted by the server, however, where I've
inserted the line:
this.fireTreeStructureChanged(parent, path, childIndecies, children);
this compiles fine but I'm still not displaying the child nodes in the
JTree. Any ideas as to why?
Please advise,
Alan
import java.io.*;
import javax.swing.tree.*;
import javax.swing.event.*;
import java.awt.Cursor;
import java.util.*;
public class MyTreeModel extends DefaultTreeModel
{
DataOutputStream output;
Response ref;
int RequestedChildCount;
private boolean ReceivedChildCount;
private boolean NodeExpanding;
RefreshTimer timer = null;
TreePath ParentNodesPath;
public MyTreeModel(TreeNode node)
{
super(node);
}
public MyTreeModel(TreeNode node, boolean asksAllowsChildren)
{
super(node, asksAllowsChildren);
}
public Object getRoot(){return root;}
public void setResponseReference(Response reference)
{
ref = reference;
}
public void setOutputStream(DataOutputStream out)
{
output = out;
}
public void insertNodeInto(DefaultTreeNode child, DefaultTreeNode
parent, int param)
{
parent.insert(child, param);
}
public int getChildCount(Object node)
{
System.out.println("Entering GetChildCount(Object)");
int count = -1;
if(node instanceof DefaultTreeNode)
{
count =
this.getChildCount(((DefaultTreeNode)node).getWholeServerPath());
}
return count;
}
public int getChildCount(String ParentsWholePath)
{
System.out.println("Entering GetChildCount(String)");
int childCount = 0;
try
{
ref.ref.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
DefaultTreeNode node = null;
String name = "";
output.writeInt(ref.ref.PATH);
output.flush();
output.writeUTF(ParentsWholePath);
output.flush();
output.writeInt(ref.ref.REQUEST_CHILD_COUNT);
output.flush();
System.out.println("waiting for response...");
timer = new MyTimer(this);
timer.start();
timer.join();
System.out.println("ReceivedChildCount: " + ReceivedChildCount +
"\nRequestedChildCount: " + RequestedChildCount);
ReceivedChildCount = false; //reset
if(RequestedChildCount > 0 & NodeExpanding)
{
RequestChildrenFromServer(ParentsWholePath);
NodeExpanding = false; //reset
}
ref.ref.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
catch(InterruptedException ie){}
catch(IOException ioe){ioe.printStackTrace();}
catch(NullPointerException npe){npe.printStackTrace();}
System.out.println("childCount: " + RequestedChildCount);
return RequestedChildCount;
}
protected void setNodeExpanding(boolean value)
{
NodeExpanding = value;
}
protected void setReceivedChildCount(boolean value)
{
ReceivedChildCount = value;
}
protected boolean getReceivedChildCount()
{
return ReceivedChildCount;
}
protected void setRequestedChildCount(int value)
{
RequestedChildCount = value;
}
protected void setParentNodesPath(TreePath path)
{
ParentNodesPath = path;
}
protected void RequestChildrenFromServer(String ParentsWholePath)
{
System.out.println("Entering RequestChildrenFromServer()");
System.out.println("ParentsWholePath: " + ParentsWholePath);
//Request Children from server
try
{
ref.ref.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
output.writeInt(ref.ref.PATH);
output.flush();
output.writeUTF(ParentsWholePath);
output.flush();
//Sending REQUEST_CHILDREN should cause a response
//from the server: SENDING_TREE_DATA
output.writeInt(ref.ref.REQUEST_CHILDREN);
output.flush();
ref.ref.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
catch(IOException ioe){ioe.printStackTrace();}
}
protected void ReceiveChildrenFromServer(DefaultTreeNode parent, String
ParentsWholePath, DataInputStream input)
{
//If we already have the child nodes for this parent node then just
return out of here.
if(parent.getHasChildren())return;
System.out.println("Entering ReceiveChildrenFromServer()");
DefaultTreeNode child = null;
int[] childIndecies = null;
Object[] children = null;
String name = "";
try
{
ref.ref.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
//read in the number of children from the server
int childCount = input.readInt();
//System.out.println("Childcount: " + childCount);
int nodeType = 0;//default
//iterate through each of the children as they come in
//from the server.
childIndecies = new int[childCount];
children = new DefaultTreeNode[childCount];
for(int i = 0; i < childCount; i++)
{
name = input.readUTF(); //get the name
System.out.println("child node: " + name);
child = new DefaultTreeNode(name); //create a new child node
//determine if this node is a directory
//or a file. Empty directories are denoted
//as having (nodeType == -1)
nodeType = input.readInt();
System.out.println("node type: " + nodeType);
if(nodeType == 0)
{
//Since a file is a leaf node
//we won't be needing to continue
//reading in nodes for it.
child.setAllowsChildren(false);
child.setHasChildren(false);
child.setLeadingPath(ParentsWholePath);
if(ref.ref.serverOS.equals("Windows"))
child.setSeparator("\\");
else
child.setSeparator("/");
}
else if(nodeType == -1)
{
child.setAllowsChildren(true); //It's an empty directory
child.setHasChildren(false);
child.setLeadingPath(ParentsWholePath);
if(ref.ref.serverOS.equals("Windows"))
child.setSeparator("\\");
else
child.setSeparator("/");
}
else
{
child.setAllowsChildren(true); //It's a directory
child.setHasChildren(true);
child.setLeadingPath(ParentsWholePath);
if(ref.ref.serverOS.equals("Windows"))
child.setSeparator("\\");
else
child.setSeparator("/");
}
insertNodeInto(child, parent, i);
childIndecies[i] = i;
children[i] = child;
}
Object[] path = new TreePath[1];
path[0] = ParentNodesPath;
this.fireTreeStructureChanged(parent, path, childIndecies,
children); //<<< Here is the method you recommeded I call
ref.ref.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
catch(IOException ioe){ioe.printStackTrace();}
catch(NullPointerException npe){npe.printStackTrace();}
}
}
"Tor Iver Wilhelmsen (TeamB)" <tor.wilhelmsen@ergo.no> wrote in message
news:u3cdgqvx4.fsf@ergo.no...
> "Alan Shiers" <ashiers@hfx.eastlink.ca> writes:
>
> > This method does what it is supposed to, however, once it has
> > populated the parent node, I expected the JTree to display the
> > nodes. This is not happening. Can someone please explain how I get
> > the JTree to then display the child nodes.
>
> You need to tell the view. In the model, call
> fireTreeStructureChanged() for the TreePath down to where they were
> inserted.
>
> (To get the fire* methods generated for you, use the BeansExpress
> events tab and click TreeModel in the list of events to fire.)
Technical Details
Message-ID:
<3f9c6527$2@newsgroups.borland.com>Path:
arc1-ca.pugleaf.net!archiver1.google.com!news2.google.com!news.maxwell.syr.edu!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mailReferences:
<3f9ae29b$1@newsgroups.borland.com> <u3cdgqvx4.fsf@ergo.no>Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 111d45,63f1d22919caaa01 X-Google-Attributes: gid111d45,public X-Google-ArrivalTime: 2003-10-26 16:39:05 PST From: "Alan Shiers" <ashiers@hfx.eastlink.ca> Newsgroups: borland.public.jbuilder.java.swing References: <3f9ae29b$1@newsgroups.borland.com> <u3cdgqvx4.fsf@ergo.no> Subject: Re: displaying child nodes on demand Date: Sun, 26 Oct 2003 20:14:36 -0400 Lines: 289 X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2800.1158 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165 NNTP-Posting-Host: 24.222.101.2 Message-ID: <3f9c6527$2@newsgroups.borland.com> X-Trace: newsgroups.borland.com 1067214119 24.222.101.2 (26 Oct 2003 16:21:59 -0700) Path: arc1-ca.pugleaf.net!archiver1.google.com!news2.google.com!news.maxwell.syr.edu!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail