# Interface DataNode

All Known Implementing Classes:
  `BranchDataNode, CompressedDataNode, DefaultDataNode, DocumentDataNode, EmptyDataNode, ErrorDataNode, FileDataNode, FITSDataNode, FITSFileDataNode, FITSStreamDataNode, HDUDataNode, HTMLDataNode, ImageHDUDataNode, JDBCDataNode, PlainDataNode, ResourceListDataNode, ScalarDataNode, StarTableDataNode, TableHDUDataNode, TarBranchDataNode, TarStreamDataNode, TfitsDataNode, TfitsHduDataNode, VOComponentDataNode, VOTableDataNode, VOTableTableDataNode, XMLDataNode, ZipArchiveDataNode, ZipBranchDataNode, ZipFileDataNode, ZipStreamDataNode`

public interface DataNode
This interface represents a node suitable for use in a tree viewer. From a data point of view, it represents a node which may have zero or more children - the node must be able to supply its own children on request. From a GUI point of view it supplies methods which can be used to represent the node, such as a name, an icon and an opportunity to do custom configuration of an object which provides more detailed (graphical) description of the node.

Implementing classes will normally also supply one or more constructors based on other classes (for instance `String`, `File` or other types of `DataNode`) - such constructors should throw a `NoSuchDataException` if the construction fails. When a `DataNodeFactory` instance is informed of the existence of this new `DataNode` implementation, it can try to construct a new object of this type from child nodes generated by this or other classes. In this way a `DataNode` of a given type does not need to know all about the kinds of child nodes it can have.

For smooth working of the node building machinery, DataNode implementations should make every effort to observe the following rules about resource usage: As far as possible, internal state of a DataNode should be constructed just-in-time as it is required rather than up front in the constructor. This is because in many cases a large number of nodes will be constructed, most of which will only be called upon to supply their name, icon, description etc; if many allocate large amounts of memory, memory is liable to be exhausted. The only actions which should be permitted to cause a (potentially) large memory allocation are:

- Invocation of `getChildIterator()`
- The user selecting one of the non-default panels in the DetailViewer

In particular the following actions should not cause large resource allocation:

- DataNode construction
- Invocation of `configureDetail(DetailViewer)`

Although you can implement this interface directly and everything should work fine, it is probably a good idea to inherit from `DefaultDataNode`. The separation of interface and implementation is as much for clarity of documentation as anything.

Version:
  $Id$
Author:
  Mark Taylor (Starlink)

## Method Summary

Modifier and Type
Method
Description
`boolean`
`allowsChildren()`
Indicates whether the node can in principle have child nodes.
`void`
`configureDetail(DetailViewer dv)`
Configures a DetailViewer object to show additional class-specific details associated with this node.
`Iterator`
`getChildIterator()`
Gets an Iterator over the children of the object, each of which should itself be a `DataNode`.
`DataNodeFactory`
`getChildMaker()`
Gets the factory which should in general be used to generate descendant nodes.
`CreationState`
`getCreator()`
Retrieves information about how this node was created.
`Object`
`getDataObject(DataType type)`
Returns a data object of a given type which corresponds to this node.
`String`
`getDescription()`
Gets a concise description of this object.
`Icon`
`getIcon()`
Gets an `Icon` which can be used when displaying this node.
`String`
`getLabel()`
Gets the label of this object.
`String`
`getName()`
Gets the name of this object.
`String`
`getNodeTLA()`
Returns a short string indicating what kind of node this is.
`String`
`getNodeType()`
Returns a short sentence indicating what kind of node this is.
`Object`
`getParentObject()`
Returns an object which is in some sense the parent of the one this node is based on.
`String`
`getPathElement()`
Gets the contribution of this node to a pathname.
`String`
`getPathSeparator()`
Gets the delimiter string which separates the name of this node from the name of one of its children when constructing a pathname.
`boolean`
`hasDataObject(DataType type)`
Indicates whether this node can, on request, supply a data object of a particular type.
`void`
`setChildMaker(DataNodeFactory factory)`
Sets the factory which should in general be used to generate child nodes.
`void`
`setCreator(CreationState state)`
Stores information about how this node was created.
`void`
`setLabel(String label)`
Sets a label for this object.
`void`
`setParentObject(Object parentObj)`
Sets the object which is in some sense the parent of the one this node is based on.

## Method Details

### allowsChildren

boolean allowsChildren()
Indicates whether the node can in principle have child nodes. Note this does not actually mean that it has any children.

Returns:
  `true` if the node is of a type which can have child nodes, `false` otherwise

### setLabel

void setLabel(String label)
Sets a label for this object. This is like a name but is not intrinsic to the object, so users of implementing classes may call this method to impose a label of their own.

Parameters:
  `label` - the label to be given to this object

### getChildIterator

Iterator getChildIterator()
Gets an Iterator over the children of the object, each of which should itself be a `DataNode`. Should only be called if `hasChildren` returns `true`. It is preferred that this method completes quickly, so if constructing the whole list of children may be time-consuming, implementing classes should avoid constructing the whole list before returning the iterator.

Implementing classes should in general follow this strategy when generating children: the class should get the list of children in whatever way is appropriate for the type of node in question. It should then make use of its childMaker (the `DataNodeFactory` returned by the `getChildMaker` method) to turn these into `DataNode` objects to return as the children rather than using a particular constructor, such as one of its own, to generate them. In this way, children may turn out to be more specific objects of a type known about by `DataNodeFactory` but not by the implementing class.

Returns:
  an `Iterator` over the children. Each object iterated over should be a `DataNode`. Behaviour is undefined if this method is called on an object for which `allowsChildren` returns `false`.

### getParentObject

Object getParentObject()
Returns an object which is in some sense the parent of the one this node is based on. The parent is not a `DataNode`, it is something which may get fed to a `DataNodeFactory` to create `DataNode`. If no such object exists, which may well be the case, `null` should be returned.

Returns:
  an object which is the parent of this one, or `null`

### setParentObject

void setParentObject(Object parentObj)
Sets the object which is in some sense the parent of the one this node is based on. The parent is not a `DataNode`, it is something which may get fed to a `DataNodeFactory` to create `DataNode`.

Parameters:
  `parentObj` - an object which is the parent of this one

### getLabel

String getLabel()
Gets the label of this object. This ought to return the same value `getName` unless the user of the implementing class has previously called `setLabel` to change it.

Returns:
  the label of the object

### getName

String getName()
Gets the name of this object. This is an intrinsic property of the object.

Returns:
  the name of the object

### getNodeTLA

String getNodeTLA()
Returns a short string indicating what kind of node this is. The return value should preferably be a Three Letter Acronym. As a rough guideline the return value should indicate what the implementing class is.

Returns:
  an abbreviated description of the type of this `DataNode`

### getNodeType

String getNodeType()
Returns a short sentence indicating what kind of node this is. The return value should be just a few words. As a rough guideline it should indicate what the implementing class is.

Returns:
  a short description of the type of this `DataNode`

### getDescription

String getDescription()
Gets a concise description of this object. The form of the description will depend on the type of node, but it might detail the shape or type of data represented, or otherwise give some information additional to the name. It should not include the return value of the `getName` method, since they may be presented together. It should be on one line, and preferably no longer than around 70 characters. The `null` value may be returned if there is nothing to say.

Returns:
  a short string describing this object

### getIcon

Icon getIcon()
Gets an `Icon` which can be used when displaying this node. This should return an icon suitable for displaying in a JTree, ideally about 16x16 pixels. It should give some indication of the type of node.

Implementations are encouraged to construct this icon lazily (i.e. not do it until this method is called), since using Icons usually causes a large number of Swing classes to be loaded, and in some circumstances (such as treeview -text) these may never be used.

Returns:
  an `Icon` for display

### getPathElement

String getPathElement()
Gets the contribution of this node to a pathname. The return value should be the name of this node as it forms part of a path name. This may or may not be equal to the `name` member variable. Can be null to indicate the no pathname can be formed from this node.

Returns:
  pathname name of this node

### getPathSeparator

String getPathSeparator()
Gets the delimiter string which separates the name of this node from the name of one of its children when constructing a pathname. If `null` is returned it indicates that no pathname can be formed from this node and one of its children (for instance if it has no children).

Returns:
  short delimiter string

### hasDataObject

boolean hasDataObject(DataType type)
Indicates whether this node can, on request, supply a data object of a particular type. The idea is that if this node corresponds to a generic object such as a table, array, etc then components can ascertain that and present it in ways appropriate to that fact. If a DataNode claims to have an object for one of the defined `DataType`s, it can in general forget about any special presentation specific to that type, on the grounds that generic node processing will take care of it.

Invoking this method ought not to create such a data object if that is an expensive process, merely to indicate whether a subsequent invocation of `getDataObject(DataType)` using the same `type` is likely to be successful.

Parameters:
  `type` - data object type of interest
Returns:
  true iff a subsequent call of `getDataObject(type)` is likely to be successful

### getDataObject

Object getDataObject(DataType type) throws DataObjectException
Returns a data object of a given type which corresponds to this node. This method should only be invoked if a prior invocation of `hasDataObject(DataType)` using the same `type` has returned true (otherwise an `IllegalArgumentException` may be thrown). The returned object must be in instance of the class returned by `type.getDataClass()`.

Parameters:
  `type` - data object type of interest
Returns:
  data object of type `type`
Throws:
  `DataObjectException`

### configureDetail

void configureDetail(DetailViewer dv)
Configures a DetailViewer object to show additional class-specific details associated with this node. Implementing classes should call various methods on the given `DetailViewer` object to customise it to contain information about the node in question. This will consist of populating the main panel with basic and compact information about this node, and possibly adding further tabbed panes giving alternative views of the data attached to the node. See the documentation for `DetailViewer` for more information.

Nodes which don't have much to say about themselves may implement this method as a no-op, though it will generally be a good idea to invoke the superclass's implementation if there is a superclass.

Parameters:
  `dv` - the detail viewer which this node is given an opportunity to configure

### setChildMaker

void setChildMaker(DataNodeFactory factory)
Sets the factory which should in general be used to generate child nodes. This is not necessarily the factory which is used for generating children of this node, since this node may have special procedures for generating children. However it is the factory which should in general be used for creating descendants of this node.

This method should only be used by applications which wish to restrict the type of node which can appear in a whole subtree of the node hierarchy. The childMaker is normally inherited from parent to child, so for instance customising the childMaker of the tree root by removing certain builders will prevent such nodes from appearing anywhere in the tree.

Parameters:
  `factory` - the factory to use for generating children

### getChildMaker

DataNodeFactory getChildMaker()
Gets the factory which should in general be used to generate descendant nodes.

Returns:
  the factory used for generating children

### setCreator

void setCreator(CreationState state)
Stores information about how this node was created.

Parameters:
  `state` - an object encapsulating the means by which this node was created

### getCreator

CreationState getCreator()
Retrieves information about how this node was created.

Returns:
  an object encapsulating the means by which this node was created. May be null if no information is available