All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nuiton.jaxx.runtime.swing.tree.DefaultIterableTreeNode Maven / Gradle / Ivy

There is a newer version: 3.1.5
Show newest version
package org.nuiton.jaxx.runtime.swing.tree;

/*-
 * #%L
 * JAXX :: Runtime
 * %%
 * Copyright (C) 2008 - 2024 Code Lutin, Ultreia.io
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 *
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 * #L%
 */

import javax.swing.tree.TreeNode;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

/**
 * Default implementation of a {@link IterableTreeNode}.
 * 

* Created by tchemit on 05/01/2018. * * @author Tony Chemit - [email protected] */ public class DefaultIterableTreeNode implements IterableTreeNode { private static final Enumeration> EMPTY_ENUMERATION = Collections.emptyEnumeration(); private IterableTreeNode parent; private List> children; private O userObject; private boolean allowsChildren; public DefaultIterableTreeNode(O userObject, boolean allowsChildren) { this.userObject = userObject; this.allowsChildren = allowsChildren; } @Override public IterableTreeNode getChildAt(int childIndex) { return isEmpty() ? null : children.get(childIndex); } @Override public final int getChildCount() { return isEmpty() ? 0 : children.size(); } @Override public final boolean isRoot() { return parent == null; } @Override public IterableTreeNode getRoot() { return isRoot() ? this : getParent().getRoot(); } @Override public IterableTreeNode getParent() { return parent; } @Override public final void setParent(IterableTreeNode parent) { this.parent = parent; } @Override public final int getIndex(TreeNode node) { Objects.requireNonNull(node); if (!(node instanceof DefaultIterableTreeNode)) { throw new IllegalArgumentException("node should be a DefaultIterableTreeNode, but was: " + node.getClass().getName()); } return isEmpty() ? -1 : children.indexOf(node); } @Override public final boolean getAllowsChildren() { return allowsChildren; } @Override public final void setAllowsChildren(boolean allowsChildren) { this.allowsChildren = allowsChildren; } @Override public boolean isLeaf() { return isEmpty(); } @Override public final Enumeration children() { return isEmpty() ? EMPTY_ENUMERATION : Collections.enumeration(children); } @Override public final Iterator> iterator() { return isEmpty() ? EMPTY_ITERATOR : children.iterator(); } @Override public final boolean isEmpty() { return children == null || children.isEmpty(); } @Override public final O getUserObject() { return userObject; } @Override public final void setUserObject(O userObject) { this.userObject = userObject; } @Override public final void addChild(IterableTreeNode newChild) { if (newChild != null && newChild.getParent() == this) { insertChild(newChild, getChildCount() - 1); } else { insertChild(newChild, getChildCount()); } } @Override public final void insertChild(IterableTreeNode newChild, int position) { Objects.requireNonNull(newChild); if (!allowsChildren) { throw new IllegalStateException("node does not allow children"); } else if (isNodeAncestor(newChild)) { throw new IllegalArgumentException("new child is an ancestor"); } IterableTreeNode oldParent = newChild.getParent(); if (oldParent != null) { oldParent.removeChild(newChild); } newChild.setParent(this); getNotNullChildren().add(position, newChild); } @Override public final void removeChild(IterableTreeNode child) { boolean remove = getNotNullChildren().remove(Objects.requireNonNull(child)); if (!remove) { throw new IllegalArgumentException("argument is not a child"); } child.setParent(null); } @Override public final void removeChild(int index) { IterableTreeNode childAt = getChildAt(index); removeChild(childAt); } @Override public void removeChildren() { if (isEmpty()) { return; } children.forEach(c -> c.setParent(null)); children.clear(); } @Override public void removeChildren(List> children) { children.forEach(this::removeChild); } /** * Returns true if anotherNode is an ancestor of this node * -- if it is this node, this node's parent, or an ancestor of this * node's parent. (Note that a node is considered an ancestor of itself.) * If anotherNode is null, this method returns false. This * operation is at worst O(h) where h is the distance from the root to * this node. * * @param anotherNode node to test as an ancestor of this node * @return true if this node is a descendant of anotherNode */ public final boolean isNodeAncestor(IterableTreeNode anotherNode) { if (anotherNode == null) { return false; } TreeNode ancestor = this; do { if (ancestor == anotherNode) { return true; } } while ((ancestor = ancestor.getParent()) != null); return false; } private List> getNotNullChildren() { if (children == null) { children = new LinkedList<>(); } return children; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy