Re: NSOutlineView
Re: NSOutlineView
- Subject: Re: NSOutlineView
- From: Doug Knowles <email@hidden>
- Date: Thu, 26 Jul 2001 21:49:24 -0400
Mike,
Here is (I hope) the essential elements of my implementation, re-phrased
to disguise my code:
The nodes of my tree/outline look more or less like the following. They
are Java objects that are NOT passed to NSOutlineView; instead, each one
creates an associated NSObject which is passed to NSOutlineView as a
mere token; the NSObject's do not contain any information. I use
NSObject's because I presume that an NSObject created and referenced by
the Java code is implicitly "retained" under the Objective-C runtime.
public abstract class TreeNode
{
// reference to the datasource
private ViewDataSource fDataSource;
// proxy for NSOutlineView (etc.) DataSource
protected NSObject fViewObject;
// reference to the model's record/object (i.e., the real data)
protected Record fRecord;
// children of this view node
protected Vector fViewChildren = new Vector();
// map to match view nodes with model objects
protected Hashtable fNodeMap = new Hashtable();
public TreeNode( Record rec, ViewDataSource dataSource ) {
// remember record
fRecord = rec;
// remember data source
fDataSource = dataSource;
// allocate object to use as a proxy for NSOutlineView (etc.)
fViewObject = new NSObject();
}
public NSObject getViewObject() {
return fViewObject;
}
// These methods are called to provide info to NSOutlineView
public int getNumberOfChildren() {
return fViewChildren.size();
}
public TreeNode getNthChild( int i ) {
return (TreeNode)fViewChildren.elementAt(i);
}
public boolean isExpandable() {
...
}
protected void addChild( TreeNode child, Object key ) {
fViewChildren.add( child );
fNodeMap.put( key, child );
if ( fDataSource != null ) fDataSource.reloadNode( this, true );
}
protected TreeNode getChildForObject( Object key ) {
return (TreeNode)(fNodeMap.get(key));
}
public abstract Object getValueForSelector( String selector );
public abstract void setValueForSelector( Object value, String
selector );
protected void reloadItem() {
getDataSource().reloadNode( this, false );
}
protected void reloadItem( boolean children ) {
getDataSource().reloadNode( this, children );
}
}
The NSOutlineView's datasource is also the view controller. It is also
a "pure" Java class. It implements a base class I use for data sources
for convenience only.
public class TestViewController extends MyViewController implements
MyViewDataSource
{
private NSOutlineView fOutlineView;
private TreeNode fRootNode;
// this is a map between the NSObject's I pass to NSOutlineView and
the TreeNode's that represent my data
private Hashtable fObject2NodeMap = new Hashtable();
private TreeNode getNodeForItem( Object item ) {
return (TreeNode)fObject2NodeMap.get( item );
}
// This is what NSOutlineView calls to populate the tree; "item" is
null when seeking the root of the tree,
// otherwise, it is an NSObject that was returned in a previous
call to this method
public Object outlineViewChildOfItem( NSOutlineView outlineView,
int index, Object item)
{
Object result = null;
TreeNode parentNode = null, childNode = null;
// figure out which node we're being asked about
if ( item != null ) parentNode = getNodeForItem( item );
// get the appropriate child node and it's NSObject "token"
if ( parentNode != null ) childNode = parentNode.getNthChild
( index );
else childNode = fRootNode;
result = childNode.getViewObject(); // this is the
NSObject we'll return
// add the new token to the map if it's not already in there
if ( result != null ) {
if ( fObject2NodeMap.get(result) == null ) {
fObject2NodeMap.put( result, childNode );
}
}
return result;
}
// Once NSOutlineView has a tree of NSObject's, it calls this
method for values to display in the view
public Object outlineViewObjectValueForItem( NSOutlineView outlineView,
NSTableColumn tableColumn, Object item)
{
Object result = null;
String selector = (String)tableColumn.identifier();
// here we use the Hashtable to translate the NSObject "item"
into a TreeNode
SIORecordNode node = getNodeForItem( item );
// ...and then we ask the TreeNode for the data that should
occupy the specified column
result = node.getValueForSelector(selector);
return result;
}
}
I hope this is helpful. Additional questions are welcome.
Doug K;
On Thursday, July 26, 2001, at 12:20 PM, Mike Jackson wrote:
Inside of my DataSource Object, there is the static variable root. This
is
the root ISTLFile Object. Since I keep a reference to this at all times
by
virtue of it being a Class variable and instantiated in the constructor
and
root has a reference, via a Vector of all its children, and all those
children should have a reference to all of their children, and so on,
shouldn't all those objects be kept around and not get gc'ed?
I have tried to have ISTLFile extend NSObject and implement
NSOutlineView.DataSource, but this is not working out correctly.
I try to cast the ISTLFile into an NSObject, but the compiler throw an
"inconvertable type" error.
So evidently I am still new to Java, so I am just missing something,
but any
help/Discussion on the topic would be helpful
--
Mike Jackson
www.infoscribe.com
_______________________________________________
cocoa-dev mailing list
email@hidden
http://www.lists.apple.com/mailman/listinfo/cocoa-dev