/* ========================
* 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: GroupNode.java,v 1.16 2008/12/17 22:37:53 cazenave Exp $
*
* Changes
* -------
* 9 janv. 08 : Initial public release
*
*/
package jsynoptic.plugins.java3d.tree;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Group;
import javax.media.j3d.Node;
import javax.media.j3d.SceneGraphObject;
import javax.media.j3d.Switch;
import javax.media.j3d.TransformGroup;
import javax.swing.JFileChooser;
import javax.swing.event.UndoableEditEvent;
import javax.swing.filechooser.FileFilter;
import jsynoptic.plugins.java3d.edit.AddEdit;
import simtools.ui.AggregateFileFilter;
import com.sun.j3d.loaders.IncorrectFormatException;
import com.sun.j3d.loaders.Loader;
import com.sun.j3d.loaders.ParsingErrorException;
import com.sun.j3d.loaders.Scene;
/**
* A Node to hold a Group Node
*/
public class GroupNode extends SceneGraphTreeNode {
/**
* Register nodes resources and actions
*/
static void loadResources(){
addResources("javax.media.j3d.Group", "Group");
addResources("javax.media.j3d.Switch", "Switch");
// TODO move in the right node sub class
addResources("javax.media.j3d.TransformGroup", "TransformGroup");
addActions("javax.media.j3d.Group","AddPrimitive","AddGroup","AddLight",LoadFileAction.class);
addActions("AddGroup",AddTransformGroupAction.class,AddGroupAction.class,AddSwitchAction.class,AddBranchGroupAction.class);
PrimitiveNode.loadResources();
LightNode.loadResources();
AnimatorGroupNode.loadResources();
SceneGraphTreeNode.loadResources();
addNodeClass("javax.media.j3d.Shape3D", ShapeNode.class);
ShapeNode.loadResources();
}
// required for dynamic node creation
public GroupNode(Tree tree, Object graphObject, boolean getChildren) {
super(tree, graphObject, getChildren);
}
@Override
protected void getSceneGraphChildren(ArrayList<Object> list) {
Group g=(Group)getGraphObject();
Enumeration<?> e=g.getAllChildren();
while(e.hasMoreElements()){
list.add(e.nextElement());
}
}
@Override
public SceneGraphObject addSceneGraphObject(SceneGraphObject obj){
if(obj instanceof Node){
addChild((Node)obj);
refresh();
return null;
}
throw new RuntimeException("addSceneGraphObject invalid argument ="+obj.getClass());
}
@Override
public void removeSceneGraphObject(SceneGraphObject obj, SceneGraphObject oldObj){
if(obj instanceof Node){
removeChild((Node)obj);
refresh();
return;
}
throw new RuntimeException("removeSceneGraphObject invalid argument ="+obj.getClass());
}
public void addChild(Node n) {
Group g=(Group)getGraphObject();
boolean forced=forceCapability(Group.ALLOW_CHILDREN_EXTEND);
g.addChild(n);
if(forced) restoreCapability(Group.ALLOW_CHILDREN_EXTEND);
if(_ad!=null){
_ad.attach();
_ad=null;
}
}
public void addChildUndoable(Node n){
addChild(n);
AddEdit ae=new AddEdit(this,n,null);
getTree().getUndoableEditListener().undoableEditHappened(
new UndoableEditEvent(this, ae));
}
public void removeChild(Node n) {
Group g=(Group)getGraphObject();
boolean forced=forceCapability(Group.ALLOW_CHILDREN_WRITE);
g.removeChild(n);
if(forced) restoreCapability(Group.ALLOW_CHILDREN_WRITE);
}
static class AddTransformGroupAction extends AbstractNodeAction {
// required for dynamic action creation
public AddTransformGroupAction() {
}
public void actionPerformed(ActionEvent e) {
((GroupNode)getNode()).addChildUndoable(new TransformGroup());
getNode().refresh();
}
}
static class AddBranchGroupAction extends AbstractNodeAction {
// required for dynamic action creation
public AddBranchGroupAction() {
}
public void actionPerformed(ActionEvent e) {
((GroupNode)getNode()).addChildUndoable(new BranchGroup());
getNode().refresh();
}
}
static class AddGroupAction extends AbstractNodeAction {
// required for dynamic action creation
public AddGroupAction() {
}
public void actionPerformed(ActionEvent e) {
((GroupNode)getNode()).addChildUndoable(new Group());
getNode().refresh();
}
}
static class AddSwitchAction extends AbstractNodeAction {
// required for dynamic action creation
public AddSwitchAction() {
}
public void actionPerformed(ActionEvent e) {
((GroupNode)getNode()).addChildUndoable(new Switch());
getNode().refresh();
}
}
static class LoadFileAction extends AbstractNodeAction {
static LoaderHandler handler=null;
// required for dynamic action creation
public LoadFileAction(){
}
@Override
public void actionPerformed(ActionEvent e) {
if(handler==null){
handler=new LoaderHandler();
}
if(handler.select()){
Scene sc=handler.load();
if(sc!=null){
BranchGroup bg=sc.getSceneGroup();
if(bg!=null){
GroupNode gn=(GroupNode)getNode();
gn.addChild(bg);
getNode().refresh();
}
}
}
}
}
static public class LoaderHandler{
HashMap<String, Class<? extends Loader>> classes=null;
JFileChooser chooser = null;
HashMap<FileFilter, String> filters= null;
AggregateFileFilter aggregateFilter=null;
static final String[][] extDescClass = {
{".wrl","VRML file","org.jdesktop.j3d.loaders.vrml97.VrmlLoader"},
{".lws","Lightwave 3D file","com.sun.j3d.loaders.lw3d.Lw3dLoader"},
{".obj","Wavefront file","com.sun.j3d.loaders.objectfile.ObjectFile"},
{".3ds","3DS file","com.mnstarfire.loaders3d.Loader3DS"},
{".dxf","DXF file","eupla.dxfloader.DxfLoader"}
};
File selectedFile=null;
Class<? extends Loader> loader=null;
LoaderHandler(){
// check availability of the loaders and generate
// a file chooser accordingly
for(int i=0;i<extDescClass.length;i++){
String className=extDescClass[i][2];
Class<?> c;
try {
c = Class.forName(className);
if(classes==null){
classes=new HashMap<String, Class<? extends Loader>>();
}
if(Loader.class.isAssignableFrom(c)){
Class<? extends Loader> cl=c.asSubclass(Loader.class);
classes.put(extDescClass[i][0],cl);
if(chooser==null){
chooser=new JFileChooser();
chooser.setCurrentDirectory(jsynoptic.ui.JSynoptic.gui.getPath());
chooser.setAcceptAllFileFilterUsed(false); // don't want all
filters=new HashMap<FileFilter, String>();
}
final int r=i;
FileFilter ff=new FileFilter(){
public boolean accept(File f) {
if (f.isDirectory())
return true;
String name = f.getName();
return name.toLowerCase().endsWith(
extDescClass[r][0]);
}
public String getDescription() {
return extDescClass[r][1];
}
};
filters.put(ff,extDescClass[i][0]);
chooser.addChoosableFileFilter(ff);
}
}
catch (ClassNotFoundException cnfe) {
}
}
if(chooser!=null && filters.size()>1){
aggregateFilter=new AggregateFileFilter(chooser.getChoosableFileFilters());
chooser.addChoosableFileFilter(aggregateFilter);
chooser.setFileFilter(aggregateFilter);
}
}
public boolean select(){
if(chooser==null||filters==null
||chooser.showOpenDialog(null)!=JFileChooser.APPROVE_OPTION){
return false;
}
File f=chooser.getSelectedFile();
FileFilter ff=chooser.getFileFilter();
if(ff==aggregateFilter){
ff=aggregateFilter.getFilterForFile(null, f);
}
String ext=(String)filters.get(ff);
if(ext==null){
return false;
}
Class<? extends Loader> c=classes.get(ext);
if(c==null){
return false;
}
selectedFile=f;
loader=c;
return true;
}
public Scene load() {
// TODO i18n
Loader o=null;
try {
o = loader.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
if(o==null){
System.err.println("Can not instanciate loader "+loader.getName());
return null;
}
try {
return o.load(selectedFile.getAbsolutePath());
} catch (FileNotFoundException e) {
System.err.println("Can not read file "+selectedFile.getAbsolutePath());
} catch (IncorrectFormatException e) {
e.printStackTrace();
System.err.println("Invalid file format : "+selectedFile.getAbsolutePath());
} catch (ParsingErrorException e) {
e.printStackTrace();
System.err.println("Parsing error when reading "+selectedFile.getAbsolutePath());
}
return null;
}
}
}