Interface TreeTable.Node

    • Method Detail

      • getParent

        TreeTable.Node getParent()
        Returns the parent node, or null if this node is the root of the tree.

        There is intentionally no set­Parent(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 null if none.
      • isLeaf

        boolean isLeaf()
        Returns true if this node can not 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). Tree­Table­Format does not use this value.

        Returns:
        true if this node can not 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:
        TreeTable.Node newNode = new ...; // Create a new node here.
        parent.getChildren().add(newNode);
        The collection is often a List, but not necessarily. For some implementations like the metadata tree table view, compliance to the List contract is impractical or inefficient.
        Returns:
        the children, or an empty collection if none.
      • getValue

        <V> V getValue​(TableColumn<V> column)
        Returns the value in the given column, or null if 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 null if none.
        See Also:
        Tree­Table​.get­Columns()
      • isEditable

        boolean isEditable​(TableColumn<?> column)
        Determines whether the value in the specified column is editable. If the given column is not a legal column for this Node instance, then this method returns false.
        Parameters:
        column - the column to query.
        Returns:
        true if the given column is a legal column for this Node implementation and the corresponding value is editable, or false otherwise.
      • 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 a City­Location class is defined as a (city name, latitude, longitude) tuple, then a Tree­Table​.Node could be defined to have 3 columns for the above 3 tuple components, and the user object could be the original City­Location instance.
        Returns:
        any object stored at this node by the user, or null if none.
      • equals

        boolean equals​(Object other)
        Returns true if 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 node returned by get­Parent() 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 same Platform instance, so we have a cyclic graph:
        Metadata tree example
        Node 1: Acquisition information
        Node 2:  └─Platform
        Node 3:     └─Instrument
        Node 4:        └─Platform (same instance than above)
        Node 5:           └─etc…
        The Abstract­Metadata​.as­Tree­Table() 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 with Tree­Table generating nodes with identical content as we bounce between Platform and Instrument metadata 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 same Platform content.

        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 than using Object​.equals(Object). This flexibility means that even if all above conditions are true, this is not a guarantee that this method will return true.

        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, Node implementations having a content fully determined by the wrapped user object need only the following implementation:

        @Override
        public boolean equals(Object obj) {
            return (obj instanceof MyNode) && ((MyNode) obj).getUserObject() == getUserObject();
        }
        Implementation details may vary, for example in the way to compare null user objects or by invoking Object​.equals(Object) instead than performing identity comparisons. Note however that since this method purpose is to detect cyclic graphs (see above example), user objects should be compared with equals(Object) only if their implementations are known to be safe against infinite recursivity.
        Overrides:
        equals in class Object
        Parameters:
        other - the other object to compare with this node.
        Returns:
        whether the two objects are nodes with equal values and equal children, ignoring parents.
        Since:
        0.8
      • hashCode

        int hashCode()
        Returns a hash code value consistent with the equals(Object) implementation for this node. If the equals(Object) method has not been overridden, then this hash­Code() method should not be overridden neither. Otherwise if this node content (values and children) is fully generated from the user object, then the equals(…) and hash­Code() methods may be implemented like below:
        @Override
        public boolean equals(Object obj) {
            return (obj instanceof MyNode) && ((MyNode) obj).getUserObject() == getUserObject();
        }
        
        @Override
        public int hashCode() {
            return System.identityHashCode(getUserObject());
        }
        Otherwise this method should compute a hash code based on values and children of this node, ignoring parent.
        Overrides:
        hash­Code in class Object
        Returns:
        a hash code for this node, potentially based on values and children but ignoring parent.
        Since:
        0.8