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

editor.AbstractTree Maven / Gradle / Ivy

There is a newer version: 1.18.1
Show newest version
package editor;

import editor.util.EditorUtilities;

import javax.swing.*;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 */
public abstract class AbstractTree, N extends ITreeNode> implements MutableTreeNode
{
  protected String _text;
  private NodeKind _kind;
  private N _node;
  private Map _userData;
  private T _parent;
  private List _children;

  public AbstractTree( JTree tree )
  {
    _text = "_root_";
    _kind = NodeKind.Root;
    _userData = new HashMap<>();
    _children = Collections.emptyList();
    putUserData( "_tree", tree );
  }

  public AbstractTree( NodeKind kind, N node )
  {
    this( null, kind, node );
  }
  public AbstractTree( String text, NodeKind kind, N node )
  {
    _text = text;
    _kind = kind;
    _node = node;
    _children = Collections.emptyList();
  }

  abstract public Icon getIcon();

  public JTree getTree()
  {
    T root = getRoot();
    return root == null ? null : (JTree)root.getUserData( "_tree" );
  }

  public T getRoot()
  {
    if( _kind == NodeKind.Root )
    {
      //noinspection unchecked
      return (T)this;
    }
    return getParent() == null ? null : getParent().getRoot();
  }

  public String getText()
  {
    return _text;
  }
  public void setText( String text )
  {
    _text = text;
    ((DefaultTreeModel)getTree().getModel()).nodeStructureChanged( this );
  }

  public NodeKind getKind()
  {
    return _kind;
  }

  public N getNode()
  {
    return _node;
  }

  public boolean isTerminal()
  {
    return _kind.isTerminal();
  }

  public List getChildren()
  {
    return _children;
  }

  @Override
  public void insert( MutableTreeNode child, int index )
  {
    if( _children.isEmpty() )
    {
      _children = new CopyOnWriteArrayList<>();
    }
    //noinspection unchecked
    _children.add( index, (T)child );
    child.setParent( this );
  }

  public void addViaModel( MutableTreeNode child )
  {
    EditorUtilities.invokeInDispatchThread(
      ()-> {
        JTree tree = getTree();
        if( tree != null )
        {
          DefaultTreeModel model = (DefaultTreeModel)tree.getModel();
          model.insertNodeInto( child, this, getChildCount() );
        }
        else
        {
          insert( child, getChildCount() );
        }
      } );
  }

  public void insertViaModel( MutableTreeNode child, int index )
  {
    EditorUtilities.invokeInDispatchThread(
     ()-> {
       JTree tree = getTree();
       if( tree != null )
       {
         DefaultTreeModel model = (DefaultTreeModel)tree.getModel();
         model.insertNodeInto( child, this, index );
       }
     } );
  }

  @Override
  public void remove( int index )
  {
    remove( getChildren().get( index ) );
  }

  @Override
  public void remove( MutableTreeNode node )
  {
    //noinspection SuspiciousMethodCalls
    getChildren().remove( node );
  }

  @Override
  public void setUserObject( Object object )
  {
  }

  public void putUserData( String name, Object value )
  {
    if( _userData == null )
    {
      _userData = new HashMap<>();
    }
    _userData.put( name, value );
  }
  public Object getUserData( String name )
  {
    if( _userData == null )
    {
      return null;
    }
    return _userData.get( name );
  }

  @Override
  public void removeFromParent()
  {
    _parent.remove( this );
  }

  @Override
  public void setParent( MutableTreeNode newParent )
  {
    //noinspection unchecked
    _parent = (T)newParent;
  }

  @Override
  public T getChildAt( int childIndex )
  {
    return getChildren().get( childIndex );
  }

  @Override
  public int getChildCount()
  {
    return getChildren().size();
  }

  @Override
  public T getParent()
  {
    return _parent;
  }

  @Override
  public int getIndex( TreeNode node )
  {
    //noinspection SuspiciousMethodCalls
    return getChildren().indexOf( node );
  }

  @Override
  public boolean getAllowsChildren()
  {
    return !_kind.isTerminal();
  }

  @Override
  public boolean isLeaf()
  {
    return isTerminal();
  }

  @Override
  public Enumeration children()
  {
    Iterator iter = getChildren().iterator();
    return new Enumeration()
    {
      @Override
      public boolean hasMoreElements()
      {
        return iter.hasNext();
      }

      @Override
      public Object nextElement()
      {
        return iter.next();
      }
    };
  }

  public String toString()
  {
    return _text;
  }

  public void select()
  {
    JTree tree = getTree();
    TreePath path = getPath();
    tree.expandPath( path );
    tree.setSelectionPath( path );
    tree.scrollPathToVisible( path );
  }

  public TreePath getPath()
  {
    List path = makePath( new ArrayList<>() );
    return new TreePath( path.toArray( new AbstractTree[path.size()] ) );
  }

  List makePath( List path )
  {
    if( getParent() != null )
    {
      getParent().makePath( path );
    }
    //noinspection unchecked
    path.add( (T)this );
    return path;
  }

  public boolean hasFailures()
  {
    //noinspection Convert2MethodRef
    return _kind == NodeKind.Failure || getChildren().stream().anyMatch( child -> child.hasFailures() );
  }

  public boolean hasErrors()
  {
    //noinspection Convert2MethodRef
    return _kind == NodeKind.Error || getChildren().stream().anyMatch( child -> child.hasErrors() );
  }

  public boolean hasWarnings()
  {
    //noinspection Convert2MethodRef
    return _kind == NodeKind.Warning || getChildren().stream().anyMatch( child -> child.hasWarnings() );
  }

  public int depth()
  {
    int depth = 0;
    //noinspection unchecked
    T csr = (T)this;
    while( csr.getParent() != null )
    {
      csr = csr.getParent();
      depth++;
    }
    return depth;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy