View Javadoc

1   /* -------------------------------------------------------------------
2    * Java source file for the class BranchGroup
3    * 
4    * Copyright (c), 2003, Masahiro Takatsuka.
5    * All Rights Researved.
6    * 
7    * Original Author: Masahiro Takatsuka (masa@jbeans.net)
8    * $Author: takatsukam $
9    * 
10   * $Date: 2004/03/03 11:53:06 $
11   * 
12   * $Id: BranchGroup.java,v 1.3 2004/03/03 11:53:06 takatsukam Exp $
13   * 
14   * Reference:		Document no:
15   * ___				___
16   * 
17   * To Do:
18   * ___
19   * 
20  ------------------------------------------------------------------- */
21  
22  /* --------------------------- Package ---------------------------- */
23  package net.jbeans.j3d.scenegraph;
24  
25  /* ------------------ Import classes (packages) ------------------- *//package-summary/html">class="comment"> ------------------ Import classes (packages) ------------------- *//package-summary.html">class="comment">/* ------------------ Import classes (packages) ------------------- *//package-summary.html">class="comment"> ------------------ Import classes (packages) ------------------- */
26  import java.io.*;
27  import java.util.*;
28  import javax.swing.event.*;
29  import javax.media.j3d.Group;
30  import javax.media.j3d.Node;
31  
32  import net.jbeans.j3d.event.*;
33  import net.jbeans.util.*;
34  import net.jbeans.util.debug.*;
35  
36  /*====================================================================
37                   Implementation of class BranchGroup                  
38  ====================================================================*/
39  /***
40   * generally describe BranchGroup in here
41   * 
42   * @version $Revision: 1.3 $
43   * @author Masahiro Takatsuka (masa@jbeans.net)
44   * @see javax.media.j3d.BranchGroup
45   * @see Serializable
46   */
47  
48  public class BranchGroup extends javax.media.j3d.BranchGroup implements Serializable {
49  	private static final boolean DEBUG = Debug.getDebugFlag(BranchGroup.class);
50  
51  	
52  	/* ------------------------ not serialized ------------------------ */
53  	transient private EventListenerList sceneGraphObjectListeners;
54  	transient private EventObject myEvent;
55  	
56  	public BranchGroup () {
57  		super();
58  		initialize();
59  	}
60  
61  	private final void initialize() {
62  		this.sceneGraphObjectListeners = new EventListenerList();
63  		this.myEvent = new EventObject(this);
64  		setCapabilities();
65  	}
66  
67  	public void setUserData(Object userData) {
68  		if (userData instanceof BranchGroup) {
69  			BranchGroup bg = (BranchGroup) userData;
70  			if (DEBUG) {
71  				System.out.println("BranchGroup:numChildren of userData = " + bg.numChildren());
72  			}
73  			if (bg.numChildren() == 0) {
74  				// ignore this!
75  				return;
76  			}
77  		}
78  		super.setUserData(userData);
79  	}
80  
81  	private final void setCapabilities() {
82  		setCapability(ALLOW_DETACH);
83  		setCapability(Group.ALLOW_CHILDREN_EXTEND);
84  		setCapability(Group.ALLOW_CHILDREN_READ);
85  		setCapability(Group.ALLOW_CHILDREN_WRITE);
86  		setCapability(Group.ALLOW_COLLISION_BOUNDS_READ);
87  		setCapability(Group.ALLOW_COLLISION_BOUNDS_WRITE);		
88  		setCapability(Node.ALLOW_AUTO_COMPUTE_BOUNDS_READ);
89  		setCapability(Node.ALLOW_AUTO_COMPUTE_BOUNDS_WRITE);		
90  		setCapability(Node.ALLOW_BOUNDS_READ);
91  		setCapability(Node.ALLOW_BOUNDS_WRITE);		
92  		setCapability(Node.ALLOW_COLLIDABLE_READ);
93  		setCapability(Node.ALLOW_COLLIDABLE_WRITE);		
94  		setCapability(Node.ALLOW_PICKABLE_READ);
95  		setCapability(Node.ALLOW_PICKABLE_WRITE);
96  
97  		setBoundsAutoCompute(true);
98  	}
99  	
100 	public void addChild(Object child) {
101 		if (child instanceof Node) {
102 			addChild((Node) child);
103 		} else if (ArrayUtil.isArray(child)) {
104 			Object[] childs = (Object[]) child;
105 			int num = childs.length;
106 			for (int i = 0; i < num; i++) {
107 				addChild((Object) childs[i]);
108 			}
109 		}
110 	}
111 
112 	public void addChild(Node child) {
113 		try {
114 			Node childParent = child.getParent();
115 			if (childParent != null) { // already a part of a scenegraph!
116 				// don't do anything, just return;
117 				if (DEBUG) {
118 					System.out.println("BranchGroup.addChild() : it already has a parent");
119 				}
120 			} else {
121 				if (child instanceof BranchGroup) {
122 					if (DEBUG) {
123 						System.out.println("BranchGroup: adding BranchGroup");
124 					}
125 					super.addChild(child);
126 				} else {
127 					Object parent = getUserData();
128 					if ((parent != null) &&
129 						(parent instanceof Group)) {
130 						// detach "this" from the scenegraph first
131 						detach();
132 						// then add a child
133 						if (DEBUG) {
134 							System.out.println("BranchGroup: adding Node (parent)");
135 						}
136 						super.addChild(child);
137 						((Group) parent).addChild(this);
138 					} else {
139 						if (DEBUG) {
140 							System.out.println("BranchGroup: adding Node = " + child);
141 						}
142 						super.addChild(child);
143 					}
144 				}
145 			}
146 		} catch (Exception e) {
147 			if (DEBUG) {
148 				e.printStackTrace();
149 			}
150 			// already a part of a scenegraph
151 			// don't do anything, just return
152 		}
153 		fireSceneGraphObjectChanged();
154 	}
155 	
156 	/***
157 	 *
158 	 */
159 	public void removeChild(Node child) {
160 		/*
161 		 * I could use Enumerator to go throgh all child but
162 		 * direct access might be faster..
163 		 */
164 		int allCnt = numChildren();
165 		int i = -1;
166 		for (i = 0; i < allCnt; i++) {
167 			if (child.equals(getChild(i))) {
168 				Object parent = getUserData();
169 				if ((parent != null) &&
170 					(parent instanceof Group)) {
171 					// detach "this" from the scenegraph first
172 					detach();
173 					// then remove a child
174 					removeChild(i);
175 					// then re atach "this" to the scenegraph.
176 					((Group) parent).addChild(this);
177 				}
178 				return;
179 			}
180 		}
181 		/*
182 		 * this method does not have to fire fireSceneGraphObjectChanged()
183 		 */
184 	}
185 
186 	/***
187      * adds an SceneGraphObjectListener to the shape.
188 	 * There should be only one listener, which is the parent of
189 	 * this BranchGroup.
190      */
191     public void addSceneGraphObjectListener(SceneGraphObjectListener l) {
192         this.sceneGraphObjectListeners.add(SceneGraphObjectListener.class, l);
193     }
194 
195     /***
196      * removes an SceneGraphObjectListener from the branchGroup.
197      */
198     public void removeSceneGraphObjectListener(SceneGraphObjectListener l) {
199 		this.sceneGraphObjectListeners.remove(SceneGraphObjectListener.class, l);
200 		/*
201 		* This code is no longer used since BranchGroup is added to
202 		* J3DRenderer using "self" connector.
203 		* Masahiro Takatsuka/2001-Jul-14
204 		*/
205 
206 		/* the lister "l" might have a reference of this object.
207 		   so, remove it!
208 		*/
209 //  		if (l instanceof Proxy) {
210 //  			InvocationHandler handler = Proxy.getInvocationHandler(l);
211 //  			Object target = AdapterHandler.getTarget(handler);
212 //  			if (DEBUG) {
213 //  				System.out.println("target = " + target);
214 //  			}
215 //  			if (target != null) {
216 //  				try {
217 //  					Object[] args = {this};
218 //  					Class[] argTypes = {BranchGroup.class};
219 //  					ClassUtil.makeObjectPerform(target, "detachBranchGraph", args, argTypes);
220 //  				} catch (Exception e) {
221 //  					if (DEBUG) {
222 //  						e.printStackTrace();
223 //  					}
224 //  				}
225 //  			}
226 //  		}
227     }
228 
229     /***
230      * Notify all listeners that have registered interest for
231      * notification on this event type.
232      */
233     public void fireSceneGraphObjectChanged() {
234         Object[] listeners = this.sceneGraphObjectListeners.getListenerList();
235         // Process the listeners last to first, notifying
236         // those that are interested in this event
237         for (int i = listeners.length - 2; i >= 0; i -= 2) {
238             if (listeners[i] == SceneGraphObjectListener.class) {
239                 // Lazily create the event:
240                 ((SceneGraphObjectListener)listeners[i+1]).objectChanged(this.myEvent);
241             }
242         }
243     }
244 
245     /***
246      * Serialization methods
247      */
248     private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException {
249 		initialize();
250     }
251 }
252