Package net.xoetrope.swing

Source Code of net.xoetrope.swing.XTree

package net.xoetrope.swing;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JTree;
import javax.swing.TransferHandler;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import net.xoetrope.swing.dnd.XTransferHandlerFactory;

import net.xoetrope.swing.tree.XTreeModelAdapter;
import net.xoetrope.xui.XAttributedComponent;
import net.xoetrope.xui.XProjectManager;
import net.xoetrope.xui.data.XModel;
import net.xoetrope.xui.events.XHandlerInvoker;
import net.xoetrope.xui.events.XListenerHelper;
import net.xoetrope.xui.style.XStyleComponent;

/**
* @todo add listeners
* @todo add data bindings
* @todo add simple path/node selection interfaces
*/

/**
* A tree control, wraps JTree
* <p>Copyright (c) Xoetrope Ltd., 1998-2004<br>
* License:      see license.txt
* $Revision: 2.4 $
*/
public class XTree extends JTree implements XAttributedComponent, TreeSelectionListener, XListenerHelper, XStyleComponent, MouseListener
{
  private XHandlerInvoker invoker;
  private XModel selectedNode, lastSelectedNode;
  private String styleName;

  /**
   * Create a new JTree component
   */
  public XTree()
  {
    setScrollsOnExpand( true );
    addTreeSelectionListener( this );
    addMouseListener( this );
  }

  /**
   * Set one or more attributes of the component.
   * @param attribName the name of the attribute
   * @param attribValue the value of the attribute
   * @return 0 for success, non zero for failure or to require some further action
   */
  public int setAttribute( String attribName, Object attribValue )
  {
    String attribNameLwr = attribName.toLowerCase();
    String attribValueStr = (String)attribValue;
    String attribValueLwr = null;
    if ( attribValue != null )
      attribValueLwr = attribValueStr.toLowerCase();
   
    if ( attribNameLwr.equals( "tooltip" ))
      setToolTipText( attribValueStr );
    else if ( attribNameLwr.equals( "dragenabled" )) {
      boolean state = "true".equals( attribValueLwr );
      setDragEnabled( state );
    }
    else
      return -1;

    return 0;
  }

  /**
    * Called whenever the value of the selection changes.
    * @param e the event that characterizes the change.
    */
  public void valueChanged(TreeSelectionEvent e)
  {
    invokeSelection();
  }

  private void invokeSelection()
  {
    getSelectedNode();
    if (( selectedNode != null ) && ( invoker != null ))
      invoker.invoke();
  }

  /**
   * Get the selected model node.
   * @return the selection
   */
  public XModel getSelectedNode()
  {
    TreePath tp = getSelectionPath();
    if ( tp != null ) {
      Object path[] = tp.getPath();
      if (( path != null ) && ( path.length > 0 )) {
        Object obj = path[ path.length - 1 ];
        if ( obj instanceof XTreeModelAdapter ) {
          XTreeModelAdapter ta = (XTreeModelAdapter)path[ path.length - 1 ];
          selectedNode = ta.getModel();
        }
      }
      else
        selectedNode = null;

      return selectedNode;
    }

    return null;
  }

  /**
   * Add an event handler response method to a component such that the page's
   * response method is invoked when the event occurs
   * @param page the page containing the method
   * @param handlerType the type of event handler
   * @param methodName the method to invoke
   * @throws NoSuchMethodException Couldn't set the handler
   */
  public void addHandler( Object page, String handlerType, String methodName ) throws NoSuchMethodException
  {
    invoker = new XHandlerInvoker( page, this, methodName );
  }

  /**
   * Set the tree style name
   * @param style the style name
   */
  public void setStyle( String style )
  {
    styleName = style;
  }

  /**
   * Get the style name
   * @return the style name
   */
  public String getStyleName()
  {
    return styleName;
  }

  /**
   * A mouse event
   * @param me the mouse event
   */
  public void mouseEntered( MouseEvent me ){}

  /**
   * A mouse event
   * @param me the mouse event
   */
  public void mouseExited( MouseEvent me ){}

  /**
   * Allow a mouse event to trigger the event if it is the same as the last
   * selection. In other cases the tree selection listener will handle the event,
   * changes the selection
   * @param me teh mouse event
   */
  public void mouseClicked( MouseEvent me )
  {
    if ( lastSelectedNode == getSelectedNode())
      invokeSelection();
    lastSelectedNode = selectedNode;
  }

  /**
   * A mouse event
   * @param me the mouse event
   */
  public void mouseReleased( MouseEvent me ){}

  /**
   * A mouse event
   * @param me the mouse event
   */
  public void mousePressed( MouseEvent me ){}
 
  /**
   * Setup drag and drop support
   * @param state true to enable drag and drop support
   */
  public void setDragEnabled( boolean state )
  {   
    if ( state ) {
      XTransferHandlerFactory thf = XTransferHandlerFactory.getInstance( XProjectManager.getCurrentProject());
      if ( thf != null ) {
        TransferHandler th = thf.getTransferHandler( this, null );
        if ( th != null ) {
          super.setDragEnabled( true );
          setTransferHandler( th );
//            addMouseListener( this );
//            addMouseMotionListener( this );
          return;
        }
      }
    }

    super.setDragEnabled( false );
  }
 
  /**
   * Find the nearest tree path in the current tree model. The method is
   * designed for use when a tree is refreshed with a new or updated model that
   * references the same objects. The tree nodes and tree paths will be
   * different in then revised model and therefore the tree methods that rely
   * on tree paths saved prior to the update will fail to find the equivalent
   * objects. This method descends the tree attempting to find the new paths
   * that reference the same (equals) objects. The search will stop if when
   * the first element in the path is not found.
   * @param tp the old path
   * @return the new path or tp if none was found, or if the path is unchanged.
   */
  public TreePath findNearestPath( TreePath tp )
  {
    if ( tp == null )
      return null;
   
    Object[] elements = tp.getPath();
    Object[] nearestPaths = new Object[ elements.length ];
   
    TreeModel tm = getModel();
    Object root = tm.getRoot();
    if ( root == null )
      return null;
       
    int idx = 0;
    nearestPaths[ idx++ ] = root;
     
    Object p = root;
    for ( int i = 1; i < elements.length; i++ ) {
      if ( elements[ i ] instanceof XTreeModelAdapter ) {
        XTreeModelAdapter tma = (XTreeModelAdapter)elements[ i ];
        XModel model = tma.getModel();
     
        int numChildren = tm.getChildCount( p );
        for ( int j = 0; j < numChildren; j++ ) {
          Object childObj = tm.getChild( p, j );
          if ( childObj instanceof XTreeModelAdapter ) {
            XTreeModelAdapter childTma = (XTreeModelAdapter)childObj;
            XModel childModel = childTma.getModel();

            if ( childModel.getId().equals( model.getId() )) {
              nearestPaths[ idx++ ] = childObj;
              p = childObj;
              break;
            }
          }
        }
      }
    }
   
    if ( idx > 0 ) {
      Object[] paths = new Object[ idx ];
      System.arraycopy( nearestPaths, 0, paths, 0, idx );
      TreePath path = new TreePath( paths );

      setSelectionPath( path );
      scrollPathToVisible( path );
      return path;
    }   

    return tp;
  }
}
TOP

Related Classes of net.xoetrope.swing.XTree

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.