- All Known Implementing Classes:
DefaultTreeTable.Node
- Enclosing interface:
TreeTable
TreeTable.Node can be seen as a
tree node associated to a single user object (like ordinary trees),
augmented with the capability to describe some aspects of the user object in predefined columns.
The list of allowed columns is given by the TreeTable.getColumns() method.
The following table summarizes the tree-related and table-related methods:
| Tree-related methods | Table-related methods |
|---|---|
Node can be associated to an arbitrary object by the
getUserObject() method. This object is not used directly by the tree tables.- Since:
- 0.3
-
Method Summary
Modifier and TypeMethodDescriptionbooleanReturnstrueif the given object is a node with the same content than this node.Returns the children of this node.Returns the parent node, ornullif this node is the root of the tree.Returns the user object associated to this node.<V> VgetValue(TableColumn<V> column) Returns the value in the given column, ornullif none.intReturns a hash code value consistent with theequals(Object)implementation for this node.booleanisEditable(TableColumn<?> column) Determines whether the value in the specified column is editable.booleanisLeaf()Returnstrueif this node cannot have any children.Creates a new child with the same columns than the other children, and adds it to the children collection.<V> voidsetValue(TableColumn<V> column, V value) Sets the value for the given column (optional operation).
-
Method Details
-
getParent
TreeTable.Node getParent()Returns the parent node, ornullif this node is the root of the tree.There is intentionally no
setParent(Node)method, as children and parent managements are highly implementation-dependant. If the children collection is modifiable, then implementations are encouraged to update automatically the parent when a child is added to or removed from that collection.- Returns:
- the parent, or
nullif none.
-
isLeaf
boolean isLeaf()Returnstrueif this node cannot have any children. The children collection of a leaf node can only be empty, and adding new child is an unsupported operation.This value is provided as a tip for graphical user interfaces, in order to determine if a node is expandable (even if empty).
TreeTableFormatdoes not use this value.- Returns:
trueif this node cannot have any children.
-
getChildren
Collection<TreeTable.Node> getChildren()Returns the children of this node. The returned collection may or may not be modifiable, at implementation choice. If the collection is modifiable, then it shall be live, i.e. any modification to the returned collection are reflected immediately in the tree. This allows addition or removal of child nodes as below:The collection is often aTreeTable.Node newNode = new ...; // Create a new node here. parent.getChildren().add(newNode);List, but not necessarily. For some implementations like the metadata tree table view, compliance to theListcontract is impractical or inefficient.- Returns:
- the children, or an empty collection if none.
-
newChild
Creates a new child with the same columns than the other children, and adds it to the children collection. The new child is typically added at the end of the collection, but this is not mandatory: implementations can add the child at whatever position they see fit.- Returns:
- the new child.
- Throws:
UnsupportedOperationException- if this node cannot add new children.
-
getValue
Returns the value in the given column, ornullif none.- Type Parameters:
V- the base type of values in the given column.- Parameters:
column- identifier of the column from which to get the value.- Returns:
- the value in the given column, or
nullif none. - See Also:
-
setValue
<V> void setValue(TableColumn<V> column, V value) throws IllegalArgumentException, UnsupportedOperationException Sets the value for the given column (optional operation). TheisEditable(TableColumn)method can be invoked before this setter method for determining if the given column is modifiable.- Type Parameters:
V- the base type of values in the given column.- Parameters:
column- identifier of the column into which to set the value.value- the value to set.- Throws:
IllegalArgumentException- if the given column is not a legal column for this node.UnsupportedOperationException- if values in the given column cannot be modified.- See Also:
-
isEditable
Determines whether the value in the specified column is editable. If the given column is not a legal column for thisNodeinstance, then this method returnsfalse.- Parameters:
column- the column to query.- Returns:
trueif the given column is a legal column for thisNodeimplementation and the corresponding value is editable, orfalseotherwise.
-
getUserObject
Object getUserObject()Returns the user object associated to this node. The user object is for information purpose only and does not appear in the rendered tree. It is typically a Java object whose content is splitted into the various table columns.Example
If aCityLocationclass is defined as a (city name, latitude, longitude) tuple, then aTreeTable.Nodecould be defined to have 3 columns for the above 3 tuple components, and the user object could be the originalCityLocationinstance.- Returns:
- any object stored at this node by the user, or
nullif none.
-
equals
Returnstrueif the given object is a node with the same content than this node. For this method, the meaning of same content is defined as below:- The given object is also a
Node. - The list returned by
TreeTable.getColumns()is equal for both nodes. - The objects returned by
getValue(TableColumn)are equal for each column. - The list returned by children is equal for both node.
getParent()shall not be taken in account. It is necessary to ignore the parent for consistency with clone and for avoiding infinite recursivity when comparing the children. A third reason is given in the purpose example below.Purpose of this method: example with ISO metadata
Consider the following tree made of ISO 19115 metadata objects: a platform containing a list of instruments, and an instrument containing a reference to the platform on which the instrument is installed. In this example, nodes 2 and 4 contain a reference to the samePlatforminstance, so we have a cyclic graph:
TheMetadata tree example Node 1: Acquisition informationNode 2: └─PlatformNode 3: └─InstrumentNode 4: └─Platform (same instance than above)Node 5: └─etc…AbstractMetadata.asTreeTable()method gives a view in which each node has its content fully generated from wrapped metadata object. Consequently, a naive walk over the above tree causes an infinite loop withTreeTablegenerating nodes with identical content as we bounce betweenPlatformandInstrumentmetadata objects. To break this loop, we need to know when the content of a node (in this example, the wrapped metadata object) has already been visited. The parent shall not be taken in account since node 2 and 4 have different parents despite having the samePlatformcontent.In this use case, the
Node.equals(Object)implementation needs only to compare the wrapped metadata (usually given by the user object) since the node content, including the list of children, is fully determined by those metadata. An identity comparison (with==) is sufficient for the purpose of avoiding infinite recursivity.Flexibility in implementations
The above list specifies minimal conditions that must be true when two nodes are considered equal. Implementations should not relax those conditions, but are free to make them more restrictive. In particular, many implementations will require that the two nodes are instances of the same class. Some implementations may also perform identity comparisons (with the==operator) between values instead of usingObject.equals(Object). This flexibility means that even if all above conditions are true, this is not a guarantee that this method will returntrue.It is okay to not override this method at all since the identity comparison inherited from
Object.equals(Object)is consistent with this method contract. Alternatively,Nodeimplementations having a content fully determined by the wrapped user object need only the following implementation:Implementation details may vary, for example in the way to compare@Override public boolean equals(Object obj) { return (obj instanceof MyNode) && ((MyNode) obj).getUserObject() == getUserObject(); }nulluser objects or by invokingObject.equals(Object)instead of performing identity comparisons. Note however that since this method purpose is to detect cyclic graphs (see above example), user objects should be compared withequals(Object)only if their implementations are known to be safe against infinite recursivity. - The given object is also a
-
hashCode
int hashCode()Returns a hash code value consistent with theequals(Object)implementation for this node. If theequals(Object)method has not been overridden, then thishashCode()method should not be overridden neither. Otherwise if this node content (values and children) is fully generated from the user object, then theequals(…)andhashCode()methods may be implemented like below:Otherwise this method should compute a hash code based on values and children of this node, ignoring parent.@Override public boolean equals(Object obj) { return (obj instanceof MyNode) && ((MyNode) obj).getUserObject() == getUserObject(); } @Override public int hashCode() { return System.identityHashCode(getUserObject()); }
-