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

org.nuiton.jaxx.runtime.swing.nav.NavNode Maven / Gradle / Ivy

The newest version!
/*
 * #%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%
 */
package org.nuiton.jaxx.runtime.swing.nav;

import org.nuiton.jaxx.runtime.swing.nav.tree.AbstractNavTreeCellRenderer;

import javax.swing.tree.TreeNode;
import java.io.Serializable;

/**
 * Definition of a node with a optional {@code childLoador} to build childs of
 * node.
 *
 * A node is identified by an {@link #getId} of an associated data of type
 * {@link #getInternalClass}.
 *
 * Note:
 * 

While using a {@code childLoador}, we can not know before node * was loaded the exact count of his childs. As a matter of facts, real leaf * nodes appears at the beginning in ui as a not leaf (there is a root handler). * When node was loaded, a leaf node will be then displayed as required. *

* *

Why NavNode is generic ?

* In a project, you should implements your own Node extending with one like this : *
 * class MyNode extends NavNode<MyNode> { ... }
 * 
* While in this class, you overrides every method with a node return type, * co-variance you'll be able to use this code : *
 * MyNode parentNode = new MyNode();
 * MyNode node = parentNode.getFirstNode();
 * 
* So for final application this generic type avoid any cast for your own node * type, this is quite convinient. * * Even if in your project, you wants to have a heriarchy of nodes, this will * still works (if you use a genercic type on your abstract nodes). *

Internal states

*
    *
  • internalClass : the type of data associated with the node
  • *
  • context : an optinal context to distinguish different types of * node with same {@code internalclass}
  • *
  • id : id of the data associated with the node
  • *
  • dirty : flag sets to {@code true} when node render MUST be recomputed
  • *
  • loaded : flag sets to {@code true} when node was loaded
  • *
  • childLoador : optional loador of childs
  • *
*

Static nodes

* Some nodes do not need auto-loading, we call them {@code static nodes}. * The method {@link #isStaticNode()} gives this state. * * Note: A static node has no {@code childLoador}. *

Node loading

* Initialy node has no data child nodes, ({@link #isLoaded()} equals * {@code false}). * when model requires node's childs, it can load them via method * {@link #populateNode(NavBridge, NavDataProvider, boolean)} * and {@link #populateChilds(NavBridge, NavDataProvider)} methods. *

Node rendering

* the {@link AbstractNavTreeCellRenderer} looks the {@link #isDirty} state to * know when render should be (re-)compute and set back the state to {@code false}. * * Each time, a node is modified, the {@link #isDirty} should be set to {@code true}. * * @author Tony Chemit - [email protected] * @since 2.1 */ public interface NavNode> extends Cloneable, TreeNode, Serializable { String getId(); String getContext(); Class getInternalClass(); boolean isLoaded(); boolean isDirty(); /** * Convinient method to known if the node is a {@code String} typed. * * @return {@code true} if the type of node if */ boolean isStringNode(); /** * To know if the node is static. * * A {@code static} node has no {@code childLoador}. * * @return {@code true} when the node is static : says, the node has * no {@code childLoador}. */ boolean isStaticNode(); /** * Gets the first node form this one to the root which has a none * {@code String} type. * * @return the first concrete node type */ N getContainerNode(); /** * Given an {@code id}, obtain the child with matching id. * * If node is NOT {@code loaded}, then first loads it (method * {@link #populateChilds(NavBridge, NavDataProvider)}) then do search * on direct childs of the node recursivly. * * @param id the id of the researched node * @param bridge model owner of nodes * @param provider data provider * @return the found node or {@code null} if not found */ N findNodeById(String id, NavBridge bridge, NavDataProvider provider); /** * Given an {@code id}, obtain the child with matching id. * * If node is NOT {@code loaded}, then first loads it (method * {@link #populateChilds(NavBridge, NavDataProvider)}) then return * on direct childs of the node. * * @param id the id of the researched node * @param bridge model owner of nodes * @param provider data provider * @return the found node or {@code null} if not found */ N getChild(String id, NavBridge bridge, NavDataProvider provider); /** * Changes the {@link #isDirty} state. * * As a side effect, when a renderer will use this node, it will force to * reload the render from the {@link NavDataProvider}. * * @param dirty the new dirty value */ void setDirty(boolean dirty); @Override boolean isLeaf(); Object getUserObject(); @Override String toString(); //-------------------------------------------------------------------------- //-- Populate methods //-------------------------------------------------------------------------- /** * To populate the node. A side-effect of this method is to set {@code dirty} * the node (renderer will recompute the render of the node). * * If {@code populateChilds} is set to {@code true}, then also populate * childs of the node using the given {@code dataProvider}. * * @param bridge le delegate modèles content le noeud * @param provider le provider de données * @param populateChilds un drapeau pour charger aussi les fils du noeud courant */ void populateNode(NavBridge bridge, NavDataProvider provider, boolean populateChilds); /** * To populate childs of the node (only when a none static node). * A side-effect of this method is to set {@code loaded} of the node. * * For a static node, do nothing. * * @param bridge model owner of the node * @param provider data provider */ void populateChilds(NavBridge bridge, NavDataProvider provider); //-------------------------------------------------------------------------- //-- Overrides to use generic type as return //-------------------------------------------------------------------------- boolean isRoot(); @Override N getParent(); void add(N node); void remove(N node); void insert(N node, int position); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy