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

io.github.palexdev.materialfx.controls.base.AbstractMFXTreeItem Maven / Gradle / Ivy

/*
 * Copyright (C) 2022 Parisi Alessandro
 * This file is part of MaterialFX (https://github.com/palexdev/MaterialFX).
 *
 * MaterialFX 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.
 *
 * MaterialFX 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with MaterialFX.  If not, see .
 */

package io.github.palexdev.materialfx.controls.base;

import io.github.palexdev.materialfx.controls.MFXTreeView;
import io.github.palexdev.materialfx.selection.base.ITreeSelectionModel;
import io.github.palexdev.materialfx.utils.TreeItemStream;
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.Control;
import javafx.util.Callback;

import java.util.List;

/**
 * Base class for every item used in {@code MFXTreeView}.
 * 

* To be precise the {@code MFXTreeView} class is just the container of the tree. * According to this implementation each item is a tree, the base concept is something like this: *

 * {@code
 * public class Node {
 *     private T data;
 *     private Node parent;
 *     private List> children;
 * }
 * }
 * 
* The root is defined as the element which parent is null. *

* * @param The type of the data within TreeItem. * @see AbstractMFXTreeCell * @see MFXTreeView * @see ITreeSelectionModel */ public abstract class AbstractMFXTreeItem extends Control { //================================================================================ // Properties //================================================================================ protected final T data; protected final ObservableList> items = FXCollections.observableArrayList(); protected AbstractMFXTreeItem parent; private final ObjectProperty> treeView = new SimpleObjectProperty<>(null); protected final ObjectProperty, AbstractMFXTreeCell>> cellFactory = new SimpleObjectProperty<>(); private final DoubleProperty childrenMargin = new SimpleDoubleProperty(20); private final BooleanProperty startExpanded = new SimpleBooleanProperty(false); private final BooleanProperty selected = new SimpleBooleanProperty(false); //================================================================================ // Constructors //================================================================================ public AbstractMFXTreeItem(T data) { this.data = data; } //================================================================================ // Abstract Methods //================================================================================ public abstract ITreeSelectionModel getSelectionModel(); protected abstract void defaultCellFactory(); protected abstract void updateChildrenParent(List> treeItems, final AbstractMFXTreeItem newParent); //================================================================================ // Methods //================================================================================ /** * Checks if the parent item is null. * * @return true if parent is null otherwise returns false */ public boolean isRoot() { return this.parent == null; } /** * Retrieves the tree's root. * * @return the root item */ public AbstractMFXTreeItem getRoot() { if (isRoot()) { return this; } AbstractMFXTreeItem par = this; while (true) { par = par.getItemParent(); if (par.isRoot()) { return par; } } } /** * Calculates the item's index in the tree structure. * * @return the item's index * @see TreeItemStream */ public long getIndex() { if (isRoot()) { return 0; } return TreeItemStream.flattenTree(getRoot()) .takeWhile(item -> !item.equals(this)) .count(); } /** * Calculates the number of items contained by this item (included). */ public long getItemsCount() { return TreeItemStream.stream(this).count(); } /** * Calculates the this item's level in the tree structure. */ public int getLevel() { if (isRoot()) { return 0; } int index = 0; AbstractMFXTreeItem par = this; while (true) { par = par.getItemParent(); index++; if (par.isRoot()) { return index; } } } /** * Retrieves the next item at the same level in the tree. * * @return the item's next sibling. Null if is root or there is no other item next */ public AbstractMFXTreeItem getNextSibling() { if (isRoot()) { return null; } List> parentItems = getItemParent().getItems(); int index = parentItems.indexOf(this); if (index == parentItems.size() - 1) { return null; } return parentItems.get(index + 1); } /** * Retrieves the previous item at the same level in the tree. * * @return the item's previous sibling. Null if is root or there is no other item before */ public AbstractMFXTreeItem getPreviousSibling() { if (isRoot()) { return null; } List> parentItems = getItemParent().getItems(); int index = parentItems.indexOf(this); if (index == 0) { return null; } return parentItems.get(index - 1); } /** * @return if this item is leaf or not. */ public boolean isLeaf() { return items.isEmpty(); } /** * Retrieves the instance of the TreeView which contains the tree. *

* The reference is stored only in the root item so this method retrieves the root first * and then returns the tree view instance. * * @return the TreeView instance */ public MFXTreeView getTreeView() { if (isRoot()) { return treeView.get(); } else { return getRoot().getTreeView(); } } public ObjectProperty> treeViewProperty() { return treeView; } /** * Sets this item's TreeView reference to the given one. *

* WARNING: THIS METHOD IS INTENDED FOR INTERNAL USE ONLY * * @see MFXTreeView */ public void setTreeView(MFXTreeView treeView) { this.treeView.set(treeView); } /** * @return the data associated with this item */ public T getData() { return data; } /** * @return the list containing this item's children */ public ObservableList> getItems() { return items; } public void setItems(ObservableList> items) { this.items.setAll(items); } /** * @return this item's parent item */ public AbstractMFXTreeItem getItemParent() { return this.parent; } /** * Sets this item's parent. This method should be called by subclasses only. *

* WARNING: THIS METHOD IS INTENDED FOR INTERNAL USE ONLY */ public void setItemParent(AbstractMFXTreeItem parent) { this.parent = parent; } /** * @return the children left margin to be used in layout. */ public double getChildrenMargin() { return childrenMargin.get(); } /** * Specifies the left margin of each children. */ public DoubleProperty childrenMarginProperty() { return childrenMargin; } /** * Sets the children left margin. */ public void setChildrenMargin(double childrenMargin) { this.childrenMargin.set(childrenMargin); } /** * @return the state of {@link #startExpandedProperty()} */ public boolean isStartExpanded() { return startExpanded.get(); } /** * Specifies whether the item should be expanded when created. */ public BooleanProperty startExpandedProperty() { return startExpanded; } /** * Sets the state of {@link #startExpandedProperty()} */ public void setStartExpanded(boolean startExpanded) { this.startExpanded.set(startExpanded); } /** * @return this item's cell factory */ public Callback, AbstractMFXTreeCell> getCellFactory() { return cellFactory.get(); } /** * Specifies the cell factory used by this item. */ public ObjectProperty, AbstractMFXTreeCell>> cellFactoryProperty() { return cellFactory; } /** * Sets the cell factory used by this item. */ public void setCellFactory(Callback, AbstractMFXTreeCell> cellFactory) { this.cellFactory.set(cellFactory); } /** * @return this item's selection state. */ public boolean isSelected() { return selected.get(); } /** * Selection property. */ public BooleanProperty selectedProperty() { return selected; } /** * Sets this item selection state. */ public void setSelected(boolean selected) { this.selected.set(selected); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy