Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* This file is part of WebLookAndFeel library.
*
* WebLookAndFeel library is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* WebLookAndFeel library 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 Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with WebLookAndFeel library. If not, see .
*/
package com.alee.laf.tree;
import com.alee.utils.CollectionUtils;
import com.alee.utils.compare.IntegerComparator;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Swing {@link DefaultTreeModel} extension.
* This model works with specific known node type and contains additional methods to affect multiple model elements at once.
*
* @param node type
* @author Mikle Garin
*/
public class WebTreeModel extends DefaultTreeModel
{
/**
* Constructs tree model with a specified node as root.
*
* @param root TreeNode object that is the root of the tree
*/
public WebTreeModel ( final N root )
{
super ( root );
}
/**
* Constructs tree model with a specified node as root.
*
* @param root TreeNode object that is the root of the tree
* @param asksAllowsChildren false if any node can have children, true if each node is asked to see if it can have children
*/
public WebTreeModel ( final N root, final boolean asksAllowsChildren )
{
super ( root, asksAllowsChildren );
}
/**
* Returns root node.
*
* @return root node
*/
public N getRootNode ()
{
return ( N ) getRoot ();
}
@Override
public void insertNodeInto ( final MutableTreeNode child, final MutableTreeNode parent, final int index )
{
// Inserting node
parent.insert ( child, index );
// Firing node addition
nodesWereInserted ( parent, new int[]{ index } );
}
/**
* Inserts a list of child nodes into parent node.
*
* @param children list of new child nodes
* @param parent parent node
* @param index insert index
*/
public void insertNodesInto ( final List children, final N parent, final int index )
{
final int count = children.size ();
if ( count > 0 )
{
// Inserting nodes
final int[] indices = new int[ count ];
for ( int i = index; i < index + count; i++ )
{
final int sourceIndex = i - index;
parent.insert ( children.get ( sourceIndex ), i );
indices[ sourceIndex ] = i;
}
// Firing nodes addition
nodesWereInserted ( parent, indices );
}
}
/**
* Inserts a list of child nodes into parent node.
*
* @param children array of new child nodes
* @param parent parent node
* @param index insert index
*/
public void insertNodesInto ( final N[] children, final N parent, final int index )
{
final int count = children.length;
if ( count > 0 )
{
// Inserting nodes
final int[] indices = new int[ count ];
for ( int i = index; i < index + count; i++ )
{
final int sourceIndex = i - index;
parent.insert ( children[ sourceIndex ], i );
indices[ sourceIndex ] = i;
}
// Firing nodes addition
nodesWereInserted ( parent, indices );
}
}
@Override
public void removeNodeFromParent ( final MutableTreeNode node )
{
// Removing nodes and collecting information on the operation
final N parent = ( N ) node.getParent ();
if ( parent == null )
{
throw new IllegalArgumentException ( "Removed node does not have a parent" );
}
final int index = parent.getIndex ( node );
parent.remove ( index );
// Firing nodes removal
nodesWereRemoved ( parent, new int[]{ index }, new Object[]{ node } );
}
/**
* Removes all child nodes under the specified node from tree structure.
*
* @param parent node to remove children from
*/
public void removeNodesFromParent ( final N parent )
{
final int count = parent.getChildCount ();
if ( count > 0 )
{
// Removing nodes and collecting information on the operation
final int[] indices = new int[ count ];
final Object[] removed = new Object[ count ];
for ( int index = 0; index < count; index++ )
{
indices[ index ] = index;
removed[ index ] = parent.getChildAt ( index );
parent.remove ( index );
}
// Firing nodes removal
nodesWereRemoved ( parent, indices, removed );
}
}
/**
* Removes specified nodes from tree structure.
*
* @param nodes nodes to remove
*/
public void removeNodesFromParent ( final N[] nodes )
{
removeNodesFromParent ( CollectionUtils.toList ( nodes ) );
}
/**
* Removes specified nodes from tree structure.
*
* @param nodes nodes to remove
*/
public void removeNodesFromParent ( final List nodes )
{
if ( nodes.size () > 0 )
{
// Collecting nodes for each parent
final Map> mappedNodes = new HashMap> ();
for ( final N node : nodes )
{
// Empty parents are ignored as they might have been removed just now
final N parent = ( N ) node.getParent ();
if ( parent != null )
{
List parentNodes = mappedNodes.get ( parent );
if ( parentNodes == null )
{
parentNodes = new ArrayList ( nodes.size () );
mappedNodes.put ( parent, parentNodes );
}
parentNodes.add ( parent.getIndex ( node ) );
}
}
// Removing mapped nodes
for ( final Map.Entry> parentEntry : mappedNodes.entrySet () )
{
// Retrieving parent and sorted indices of nodes to remove
final N parent = parentEntry.getKey ();
final List removedIndices = CollectionUtils.sort ( parentEntry.getValue (), IntegerComparator.instance () );
// Removing nodes from parent
final List removedNodes = new ArrayList ( removedIndices.size () );
for ( int i = removedIndices.size () - 1; i >= 0; i-- )
{
final int index = removedIndices.get ( i );
removedNodes.add ( ( N ) parent.getChildAt ( index ) );
parent.remove ( index );
}
// Firing removal event
final int[] indices = CollectionUtils.toIntArray ( removedIndices );
final Object[] removed = CollectionUtils.toObjectArray ( removedNodes );
nodesWereRemoved ( parent, indices, removed );
}
}
}
/**
* Forces tree node to be updated.
*
* @param node tree node to be updated
*/
public void updateNode ( final N node )
{
if ( node != null )
{
fireTreeNodesChanged ( WebTreeModel.this, getPathToRoot ( node ), null, null );
}
}
/**
* Forces tree nodes to be updated.
*
* @param nodes tree nodes to be updated
*/
public void updateNodes ( final N... nodes )
{
if ( nodes != null && nodes.length > 0 )
{
for ( final N node : nodes )
{
fireTreeNodesChanged ( WebTreeModel.this, getPathToRoot ( node ), null, null );
}
}
}
/**
* Forces tree nodes to be updated.
*
* @param nodes tree nodes to be updated
*/
public void updateNodes ( final List nodes )
{
if ( CollectionUtils.notEmpty ( nodes ) )
{
for ( final N node : nodes )
{
fireTreeNodesChanged ( WebTreeModel.this, getPathToRoot ( node ), null, null );
}
}
}
/**
* Forces tree node to be updated.
*
* @param node tree node to be updated
*/
public void updateNodeStructure ( final N node )
{
if ( node != null )
{
fireTreeStructureChanged ( WebTreeModel.this, getPathToRoot ( node ), null, null );
}
}
/**
* Forces update of all visible node sizes and view.
* This call might be useful if renderer changes dramatically and you have to update the whole tree.
*/
public void updateTree ()
{
final TreeNode[] path = TreeUtils.getPath ( getRootNode () );
fireTreeStructureChanged ( WebTreeModel.this, path, null, null );
}
}