Package syn3d.ui

Source Code of syn3d.ui.SceneGraphTree$TreeWorker

/* ========================
* JSynoptic : a free Synoptic editor
* ========================
*
* Project Info:  http://jsynoptic.sourceforge.net/index.html
*
* 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 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2001-2004, by :
*     Corporate:
*         Astrium SAS
*     Individual:
*         Claude Cazenave
*
* $Id: SceneGraphTree.java,v 1.12 2005/09/02 11:57:30 ogor Exp $
*
* Changes
* -------
* 12-Dec-2003 : Creation date (CC);
*
*/
package syn3d.ui;

import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreePath;

import syn3d.base.ActiveNode;
import syn3d.nodes.ActiveNodeTreeChangeListener;
import syn3d.nodes.SceneNode;


/**
* Class description ...
*
* @author Claude CAZENAVE
*
*/
public class SceneGraphTree extends JTree implements ActiveNodeTreeChangeListener, TreeSelectionListener {

    protected boolean autoHighlight = false;
   

  /**
   * @param newModel
   */
  public SceneGraphTree(SceneGraphModel model) {
    super(model);
    setRootVisible(false); // set to true for debug only
    setShowsRootHandles(true);
    setCellRenderer(new SceneGraphTreeRenderer());
    setExpandsSelectedPaths(true);
    setAutoscrolls(true);
     
    // Monitor structural changes to maintain selections and expanded states
    model.getRootNode().addListener(this);
    addTreeSelectionListener(this);
  }

    /**
     * Auto-highlighting means that when a node is selected in this tree, it is
     * automatically highlighted. This is false by default.<br>
     * Note: The change will occur in all trees sharing the same Node model.
     * @see ActiveNode.highlight(boolean)
     * @return Returns the autoHighlight.
     */
    public boolean isAutoHighlight() {
        return autoHighlight;
    }

    /**
     * @see isAutoHighlight()
     * @param autoHighlight The autoHighlight to set.
     */
    public void setAutoHighlight(boolean autoHighlight) {
        this.autoHighlight = autoHighlight;
    }
   
  /**
   * A helper to create a panel to contain this tree
   * @param title
   * @return
   */
  public JPanel createPanel(String title) {
    JPanel p = new JPanel();
    p.setBorder(BorderFactory.createTitledBorder(null, title));
    JScrollPane pp =
      new JScrollPane(
        this,
        JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
        JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    p.add(pp);
    return p;
  }
 
  /* (non-Javadoc)
   * @see java.lang.Object#toString()
   */
  public String toString(){
    return getName();
  }
 
  /** Utility helper to get the selected ActiveNode */
  public ActiveNode getSelectedNode() {
      return (ActiveNode)getSelectionPath().getLastPathComponent();
  }

  /** Adds all expanded path under the given tree path to the arraylist, recusrively */
  protected void recursiveExpandedPathFinder(TreePath current, ArrayList expPaths) {
        if (!isExpanded(current)) return;
        expPaths.add(current);
        ActiveNode node = (ActiveNode)current.getLastPathComponent();
      for (Iterator it = node.getChildren().iterator(); it.hasNext();) {
          recursiveExpandedPathFinder(current.pathByAddingChild((ActiveNode)it.next()),expPaths);
      }
       
  }

  /** Possible actions for TreeWorker */
  public static final int NODE_ADDED = 1;
  public static final int NODE_REMOVED = 2;
  public static final int NODE_CHANGED = 3;
 
  public class TreeWorker implements Runnable {
      protected ActiveNode node;
      protected int action;
     
      public TreeWorker(ActiveNode node, int action) {
          this.node = node;
          this.action = action;
      }
     
        public void run() {
            SceneGraphModel model = (SceneGraphModel)getModel();
           
            ActiveNode target;
            if (action==NODE_CHANGED) target = node;
            else target = node.getParent();
           
          ActiveNode[] nodePath = model.getPathToRoot(target);

          // Keep the expanded state of all children that are expanded
          ArrayList expPaths = null;
          if (action!=NODE_CHANGED) {
              expPaths = new ArrayList();
              recursiveExpandedPathFinder(new TreePath(nodePath), expPaths);
          }

          // change model to add or remove the new child to the parent node
            model.fireTreeChanged(target, nodePath, null, null);

            // Universes have their own listeners. nodePath[0] is root, 1 is universe
            // Notify only the universe concerned by the changes, not the other universes
            if ((nodePath.length>=2) && (nodePath[1] instanceof SceneNode)) {
                ((SceneNode)nodePath[1]).notifyListeners();
            }
         
          // restore expanded state
          if (action!=NODE_CHANGED) for (Iterator it = expPaths.iterator(); it.hasNext();) {
              TreePath path = (TreePath)it.next();
              expandPath(path);
          }

          // Set selection on the new element
          if (action==NODE_ADDED) setSelectionPath(new TreePath(model.getPathToRoot(node)));
          else if (action==NODE_REMOVED) setSelectionPath(new TreePath(model.getPathToRoot(target)));
        }
    }
 
    /* (non-Javadoc)
     * @see syn3d.nodes.ActiveNodeTreeChangeListener#nodeAdded(syn3d.base.ActiveNode)
     */
    public void nodeAdded(ActiveNode node) {
        // This function may be called from any thread
        // Do things properly
        SwingUtilities.invokeLater(new TreeWorker(node, NODE_ADDED));
    }

    /* (non-Javadoc)
     * @see syn3d.nodes.ActiveNodeTreeChangeListener#nodeRemoved(syn3d.base.ActiveNode)
     */
    public void nodeRemoved(ActiveNode node) {
        // This function may be called from any thread
        // Do things properly
        SwingUtilities.invokeLater(new TreeWorker(node, NODE_REMOVED));
    }

    /* (non-Javadoc)
     * @see syn3d.nodes.ActiveNodeTreeChangeListener#nameChanged(syn3d.base.ActiveNode)
     */
    public void nameChanged(ActiveNode node) {
        repaint(); // repaints posts to the AWT thread, so OK
    }

    /* (non-Javadoc)
     * @see syn3d.nodes.ActiveNodeTreeChangeListener#highlightChanged(syn3d.base.ActiveNode, boolean)
     */
    public void highlightChanged(ActiveNode node, boolean on) {
        if (!autoHighlight) return;

        // Avoid infinite recursion loop with highlightChanged notification
        boolean highlightSave = autoHighlight;
        autoHighlight = false;

        SceneGraphModel model = (SceneGraphModel)getModel();
        TreePath path = new TreePath(model.getPathToRoot(node));
        if (on) addSelectionPath(path);
        else this.removeSelectionPath(path);
       
        autoHighlight = highlightSave;
    }

    /* (non-Javadoc)
     * @see syn3d.nodes.ActiveNodeTreeChangeListener#structureChanged(syn3d.base.ActiveNode)
     */
    public void structureChanged(ActiveNode node) {
        // This function may be called from any thread
        // Do things properly
        SwingUtilities.invokeLater(new TreeWorker(node, NODE_CHANGED));
    }
   
    /* (non-Javadoc)
     * @see javax.swing.event.TreeSelectionListener#valueChanged(javax.swing.event.TreeSelectionEvent)
     */
    public void valueChanged(TreeSelectionEvent e) {
        if (!autoHighlight) return;

        // Avoid infinite recursion loop with highlightChanged notification
        boolean highlightSave = autoHighlight;
        autoHighlight = false;
       
        TreePath[] paths = e.getPaths();
        for (int i=0; i<paths.length; ++i) {
            ActiveNode node = (ActiveNode)paths[i].getLastPathComponent();
            node.highlight(e.isAddedPath(i), node.get3DObject());
        }
       
        autoHighlight = highlightSave;
    }
   
}
TOP

Related Classes of syn3d.ui.SceneGraphTree$TreeWorker

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.