Package jsynoptic.plugins.java3d.tree

Source Code of jsynoptic.plugins.java3d.tree.SceneGraphTreeNode

/* ========================
* 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-2007, by :
*     Corporate:
*         EADS Astrium
*     Individual:
*         Claude Cazenave
*
* $Id: SceneGraphTreeNode.java,v 1.2 2008/11/14 17:03:14 cazenave Exp $
*
* Changes
* -------
* 9 janv. 08  : Initial public release
*
*/
package jsynoptic.plugins.java3d.tree;

import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Enumeration;

import javax.media.j3d.Group;
import javax.media.j3d.Node;
import javax.media.j3d.NodeComponent;
import javax.media.j3d.SceneGraphObject;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.KeyStroke;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.tree.TreeNode;
import javax.swing.undo.CompoundEdit;

import simtools.ui.MenuResourceBundle;
import simtools.ui.ResourceFinder;

import jsynoptic.plugins.java3d.SceneGraphObjectHolder;
import jsynoptic.plugins.java3d.AttachDetach;
import jsynoptic.plugins.java3d.edit.AddEdit;
import jsynoptic.plugins.java3d.edit.RemoveEdit;
import jsynoptic.plugins.java3d.panels.SceneGraphObjectDialog;
import jsynoptic.ui.JSynoptic;

/**
* A Node to hold a Scene Graph Object
*/
public class SceneGraphTreeNode extends AbstractNode implements SceneGraphObjectHolder{
    /**
     * Register nodes resources and actions
     */
    static void loadResources(){
        addResources("javax.media.j3d.SceneGraphObject", "SceneGraphObject");
    }

    // Reuse some jsynoptic main ui resources
    public static MenuResourceBundle sharedResources = ResourceFinder.getMenu(JSynoptic.class);

    public static final Object NoDefaultAction=new Object();
   
    public static void addActions(String className, Object... actions) {
        if (className != null) {
            try {
                Class<?> c = Class.forName(className);
                boolean noAction=actions!=null && actions.length>0 && actions[0]==NoDefaultAction;
                if (SceneGraphObject.class.isAssignableFrom(c) && !noAction) {
                    Object[] actions2 = new Object[actions.length + 10];
                    System.arraycopy(actions, 0, actions2, 0, actions.length);
                    actions2[actions.length] = null;
                    actions2[actions.length + 1] = CutAction.class;
                    actions2[actions.length + 2] = CopyAction.class;
                    actions2[actions.length + 3] = PasteAction.class;
                    actions2[actions.length + 4] = RemoveAction.class;
                    actions2[actions.length + 5] = null;
                    actions2[actions.length + 6] = DeepCopyAction.class;
                    actions2[actions.length + 7] = DeepPasteAction.class;
                    actions2[actions.length + 8] = null;
                    actions2[actions.length + 9] = PropertiesAction.class;
                    actions = actions2;
                }
            } catch (ClassNotFoundException e) {
            }
        }
       AbstractNodeAction.addActions(className, actions);
    }

    protected AttachDetach _ad;

    // required for dynamic node creation
    public SceneGraphTreeNode(Tree tree, Object graphObject, boolean getChildren) {
        super(tree, graphObject, getChildren);
        _ad=null;
    }

    @Override
    public Node getSceneGraphNode(){

        if(getGraphObject() instanceof Node){
            return (Node)getGraphObject();
        }
        if(getParent()==null){
            return null;
        }
        if(getParent() instanceof SceneGraphTreeNode){
            return ((SceneGraphTreeNode)getParent()).getSceneGraphNode();
        }
        return null;
    }

    @Override
    public Group getSceneGraphGroup(){

        if(getGraphObject() instanceof Group){
            return (Group)getGraphObject();
        }
        if(getParent()==null){
            return null;
        }
        if(getParent() instanceof SceneGraphTreeNode){
            return ((SceneGraphTreeNode)getParent()).getSceneGraphGroup();
        }
        return null;
    }

    @Override
    public SceneGraphObject getSceneGraphObject() {
        return (SceneGraphObject)getGraphObject();
    }

    @Override
    public SceneGraphObjectHolder getParentHolder(){
        TreeNode p=getParent();
        if(p instanceof SceneGraphObjectHolder){
            return (SceneGraphObjectHolder)p;
        }
        return null;
    }
   
    @Override
    public void getChildrenHolders(ArrayList<SceneGraphObjectHolder> list){
        Enumeration<?> e=children();
        while(e.hasMoreElements()){
            Object o=e.nextElement();
            if(o instanceof SceneGraphObjectHolder){
                list.add((SceneGraphObjectHolder)o);
            }
        }
    }

    @Override
    public void getRootHolders(ArrayList<SceneGraphObjectHolder> list){
        UniverseNode un=null;
        TreeNode tn=this;
        while(un==null && tn!=null){
            tn=tn.getParent();
            if(tn instanceof UniverseNode){
                un=(UniverseNode)tn;
            }
        }
        if(un!=null){
            Enumeration<?> e=un.children();
            while(e.hasMoreElements()){
                Object o=e.nextElement();
                if(o instanceof SceneGraphObjectHolder){
                    list.add((SceneGraphObjectHolder)o);
                }
            }
        }
    }

    @Override
    public UndoableEditListener getUndoableEditListener() {
        return getTree().getUndoableEditListener();
    }

    @Override
    public String getName(){
        String sgoName=((SceneGraphObject)getGraphObject()).getName();
        if(sgoName!=null){
            return _name+"["+sgoName+"]";
        }
        return _name;
    }
   
    @Override
    protected void getSceneGraphChildren(ArrayList<Object> list) {
        return; // no child
    }
   
    /**
     * This default implementation simply checks
     * if a tree node class exists as a children of the current node
     * This is used a default rule used to check the compatibility of
     * the scene graph object with the current object
     */
    @Override
    public boolean canAddSceneGraphObject(SceneGraphObject obj){
        return getChildrenNodeClass(obj) != null;
    }
   
    @Override
    public SceneGraphObject addSceneGraphObject(SceneGraphObject obj){
        throw new RuntimeException("addSceneGraphObject invalid argument ="+obj.getClass());
    }
   
    /**
     * This default implementation simply checks
     * if a tree node class exists as a children of the current node
     * This is used a default rule used to check the compatibility of
     * the scene graph object with the current object
     */
    @Override
    public boolean canRemoveSceneGraphObject(SceneGraphObject obj, SceneGraphObject oldObj){
        return getChildrenNodeClass(obj) != null;
    }

    @Override
    public void removeSceneGraphObject(SceneGraphObject obj, SceneGraphObject oldObj){
        throw new RuntimeException("removeSceneGraphObject invalid argument ="+obj.getClass());
    }
   
    public void paste(boolean deepClone){
        ArrayList<SceneGraphTreeNode> v=getTree().getClipBoard().get();
        CompoundEdit compoundEdit = new CompoundEdit();
        for(SceneGraphTreeNode o: v){
            SceneGraphTreeNode cn=o.cloneNode(deepClone, this);
            SceneGraphObject replaced=addSceneGraphObject((SceneGraphObject)cn.getGraphObject());
            compoundEdit.addEdit(new AddEdit(this,
                    (SceneGraphObject)cn.getGraphObject(),
                    replaced));
        }
        compoundEdit.end();
        getTree().getUndoableEditListener().undoableEditHappened(
                new UndoableEditEvent(this, compoundEdit));
    }
   
    public boolean canPaste(){
        ArrayList<SceneGraphTreeNode> v=getTree().getClipBoard().get();
        if(v.size()==0){
            return false;
        }
        for(SceneGraphTreeNode o: v){
            if(!canAddSceneGraphObject((SceneGraphObject)o.getGraphObject())){
                return false;
            }
        }
        return true;
    }
   
    public void copy(boolean deepClone){
        getTree().getClipBoard().set(cloneNode(deepClone, (AbstractNode)getParent()));
    }
   
    public void cut(){
        copy(false);
        remove();
    }
   
    public boolean canRemove(){
        if(getParent() instanceof SceneGraphObjectHolder){
            SceneGraphObjectHolder owner=(SceneGraphObjectHolder)getParent();
            return owner.canRemoveSceneGraphObject((SceneGraphObject)getGraphObject(), null);
        }
        return false;
    }
   
    public void remove(){
        if(getParent() instanceof SceneGraphObjectHolder){
            SceneGraphObjectHolder owner=(SceneGraphObjectHolder)getParent();
            owner.removeSceneGraphObject((SceneGraphObject)getGraphObject(), null);
            RemoveEdit re=new RemoveEdit(owner, (SceneGraphObject)getGraphObject());
            getTree().getUndoableEditListener().undoableEditHappened(
                    new UndoableEditEvent(this, re));
        }
        else{
            throw new RuntimeException("Can not remove node from "+ getParent().getClass());
        }
    }
   
    /**
     * A generic tree node clone method
     * A new tree node is created with inside a clone of the original scene graph
     * One can override if needed
     * @param forceDuplicate if true force duplication of nodes and sub graph nodes
     * @param parent used to create a new tree node according to the cloned
     * scene graph object
     * @return a clone of the tree node with a clone of the scene graph object in
     */
    public SceneGraphTreeNode cloneNode(boolean deepClone, AbstractNode parent){
        SceneGraphObject o=(SceneGraphObject)getGraphObject();
        Node n=getSceneGraphNode();
        AttachDetach ad=null;
        if(n!=null && n.isLive()){
            ad=new AttachDetach(n);
            ad.detach();
        }
        Object clone=null;
        if(o instanceof Group){
            clone=((Group)o).cloneTree(deepClone);
        }
        else if(o instanceof Node){
            clone=((Node)o).cloneNode(deepClone);
        }
        else if(o instanceof NodeComponent){
            clone=((NodeComponent)o).cloneNodeComponent(deepClone);
        }
        else{
            if(ad!=null) ad.attach();
            throw new RuntimeException("Can not clone "+o);
        }
        if(ad!=null) ad.attach();
        return (SceneGraphTreeNode)parent.createNode(clone);
    }
   
    public boolean forceCapability(int bit){
        if(!((SceneGraphObject)getGraphObject()).getCapability(bit)){
            if(((SceneGraphObject)getGraphObject()).isLive()){
                Node n= getSceneGraphNode();
                if(_ad!=null){
                    throw new RuntimeException("Unexpected attach detach operation");
                }
                _ad=new AttachDetach(n);
                _ad.detach();
            }
            ((SceneGraphObject)getGraphObject()).setCapability(bit);
            return true;
        }
        return false;
    }
   
    public void restoreCapability(int bit){
        ((SceneGraphObject)getGraphObject()).clearCapability(bit);
        if(_ad!=null){
            _ad.attach();
            _ad=null;
        }
    }

    public static class PropertiesAction extends AbstractNodeAction {
        // required for dynamic action creation
        public PropertiesAction() {
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            SceneGraphObjectDialog.createDialog((SceneGraphTreeNode)getNode(),
                    getLocation(), null);
        }

    }

    public static class DeepCopyAction extends AbstractNodeAction {
        // required for dynamic action creation
        public DeepCopyAction() {
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            ((SceneGraphTreeNode)getNode()).copy(true);
        }
    }

    public static class DeepPasteAction extends AbstractNodeAction {
        // required for dynamic action creation
        public DeepPasteAction() {
        }
       
        @Override
        public void actionPerformed(ActionEvent e) {
            ((SceneGraphTreeNode)getNode()).paste(true);
        }
    }

    static abstract class SharedAction extends AbstractNodeAction {
        // required for dynamic action creation
        public SharedAction(String resourceKey) {
            _resourceKey=resourceKey;
        }

        protected void init() {
            putValue(Action.NAME, sharedResources.getStringValue(_resourceKey
                    + "Action"));
            ImageIcon i = sharedResources.getIcon(_resourceKey + "Image");
            if (i != null) {
                putValue(Action.SMALL_ICON, i);
            }
            KeyStroke k = sharedResources.getKeyStroke(_resourceKey + "Shortcut");
            if (k != null) {
                putValue(Action.ACCELERATOR_KEY, k);
            }
            String tip = sharedResources.getStringValue(_resourceKey + "Tip");
            putValue(Action.SHORT_DESCRIPTION, tip);
           
            validate();
        }
       
        protected void validate(){
            if(!(getNode() instanceof SceneGraphTreeNode)){
                setEnabled(false);
            }
            else{
                if(_resourceKey.equals("paste")){
                    setEnabled(((SceneGraphTreeNode)getNode()).canPaste());
                }
                else if(_resourceKey.equals("copy")){
                    SceneGraphObject o=(SceneGraphObject)getNode().getGraphObject();
                    if((o instanceof Node)||(o instanceof NodeComponent)){
                        setEnabled(true);
                    }
                    else{
                        setEnabled(false);
                    }
                }
                else if(_resourceKey.equals("cut")){
                    setEnabled(((SceneGraphTreeNode)getNode()).canRemove());
                }
                else if(_resourceKey.equals("remove")){
                    setEnabled(((SceneGraphTreeNode)getNode()).canRemove());
                }
            }
        }
       
        @Override
        public void actionPerformed(ActionEvent e) {
            if(_resourceKey.equals("paste")){
                ((SceneGraphTreeNode)getNode()).paste(false);
            }
            else if(_resourceKey.equals("cut")){
                ((SceneGraphTreeNode)getNode()).cut();
            }
            else if(_resourceKey.equals("copy")){
                ((SceneGraphTreeNode)getNode()).copy(false);
            }
            else if(_resourceKey.equals("remove")){
                ((SceneGraphTreeNode)getNode()).remove();
            }
        }
    }
   
    public static class CutAction extends SharedAction {public CutAction() {super("cut");}}
    public static class RemoveAction extends SharedAction {public RemoveAction() {super("remove");}}
    public static class PasteAction extends SharedAction {public PasteAction() {super("paste");}}
    public static class CopyAction extends SharedAction {public CopyAction() {super("copy");}}


}
TOP

Related Classes of jsynoptic.plugins.java3d.tree.SceneGraphTreeNode

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.