001: /*
002: * $Header: /cvs/j3dfly/J3dEditor/src/org/jdesktop/j3dedit/scenegrapheditor/nodeeditors/EditorManager.java,v 1.2 2007/01/26 19:31:27 paulby Exp $
003: *
004: * Sun Public License Notice
005: *
006: * The contents of this file are subject to the Sun Public License Version
007: * 1.0 (the "License"). You may not use this file except in compliance with
008: * the License. A copy of the License is available at http://www.sun.com/
009: *
010: * The Original Code is the Java 3D(tm) Scene Graph Editor.
011: * The Initial Developer of the Original Code is Paul Byrne.
012: * Portions created by Paul Byrne are Copyright (C) 2002.
013: * All Rights Reserved.
014: *
015: * Contributor(s): Paul Byrne.
016: *
017: **/
018: package org.jdesktop.j3dedit.scenegrapheditor.nodeeditors;
019:
020: import java.awt.Point;
021: import java.util.HashMap;
022:
023: import javax.swing.*;
024: import javax.media.j3d.Node;
025: import javax.media.j3d.SceneGraphObject;
026:
027: import org.jdesktop.j3dedit.scenegraph.SGObject;
028: import org.jdesktop.j3dedit.scenegraph.SGNode;
029: import org.jdesktop.j3dfly.namecontrol.NameControl;
030:
031: /**
032: * Control and monitor node being edited.
033: * Ensures that changes are applied or reset before user swithces
034: * between nodes.
035: *
036: * @author Paul Byrne
037: * @version $Id%
038: */
039: public class EditorManager {
040:
041: SGNode currentNode = null;
042:
043: EditorFrame frame;
044:
045: private NoEditorPanel noEditorPanel; // Default noEditor panel
046: private EmptyEditorPanel emptyEditorPanel; // Panel when nothing is selected
047: private NodeEditorPanel editorPanel; // Current editorPanel displayed
048:
049: private HashMap editorClasses = new HashMap(); // Mapping for Node class name to Node Editor class
050: private HashMap sharedPanels = new HashMap(); // All the editor panels
051: private boolean readOnly;
052:
053: private boolean capabilitiesChanged;
054:
055: public EditorManager() {
056: this (false);
057: }
058:
059: public EditorManager(boolean readOnly) {
060: this .readOnly = readOnly;
061: frame = new EditorFrame(this );
062:
063: noEditorPanel = new NoEditorPanel();
064: emptyEditorPanel = new EmptyEditorPanel();
065: editorPanel = emptyEditorPanel;
066: frame.showPanel(emptyEditorPanel);
067: }
068:
069: /**
070: * Set the editor windows to be read-only.
071: * The user will be unable to make any changes
072: */
073: public void setReadOnly(boolean readOnly) {
074: this .readOnly = readOnly;
075: frame.setReadOnly(readOnly);
076: }
077:
078: public boolean getReadOnly() {
079: return readOnly;
080: }
081:
082: /**
083: * Get the node which is currently being edited
084: */
085: public SGObject getCurrentNode() {
086: return currentNode;
087: }
088:
089: /**
090: * Get the frame that contains the component editors
091: */
092: public EditorFrame getEditorFrame() {
093: return frame;
094: }
095:
096: public void setActive(boolean active) {
097: frame.setVisible(active);
098: }
099:
100: /**
101: * Set the capabilities of this node to the correct values
102: * depending on the Editor mode.
103: *
104: * Node must not be live
105: *
106: * The nodes original capabilites were stored by the SGObject when the
107: * setJ3dNode was called.
108: */
109: public void setEditorCapabilities(SGObject node) {
110: NodeEditorPanel tmp = findEditorPanel((Node) node
111: .getJ3dSceneGraphObject());
112:
113: if (tmp == null)
114: return;
115:
116: tmp.setEditorCapabilities((Node) node.getJ3dSceneGraphObject());
117:
118: if (org.jdesktop.j3dedit.scenegrapheditor.PropertiesDialog.performanceLevel == org.jdesktop.j3dedit.scenegrapheditor.PropertiesDialog.READ_WRITE_ALLOWED)
119: node
120: .setEditorCapabilitiesStatus(SGObject.CAPABILITIES_READ_WRITE);
121: else if (org.jdesktop.j3dedit.scenegrapheditor.PropertiesDialog.performanceLevel == org.jdesktop.j3dedit.scenegrapheditor.PropertiesDialog.READ_ALLOWED)
122: node
123: .setEditorCapabilitiesStatus(SGObject.CAPABILITIES_READ);
124: }
125:
126: /**
127: * Set the editor class used to edit the specified J3d node. This is called by
128: * ConfigLoader
129: */
130: public void setEditorClass(String j3dNodeClassName,
131: Class editorClass) {
132: Object obj = editorClasses.put(j3dNodeClassName, editorClass);
133:
134: //System.out.println( j3dNodeClassName +" "+ editorClass );
135:
136: if (obj != null)
137: System.out
138: .println("WARNING - config file has multiple entries for "
139: + j3dNodeClassName);
140: }
141:
142: /**
143: * Called by EditorFrame when apply button is pressed
144: */
145: void applyChanges() {
146: editorPanel.applyChanges();
147:
148: notifyNameChange(editorPanel.getNodeName());
149: currentNode.repaint();
150: }
151:
152: void notifyNameChange(String name) {
153: if (name == currentNode.getJ3dNode().getName())
154: return;
155:
156: currentNode.getJ3dNode().setName(editorPanel.getNodeName());
157: if (currentNode.getNodeName() == null) {
158: if (name != null)
159: currentNode.getContext().getNameControl().addObject(
160: currentNode.getSceneName(), name, // New name
161: ((SGNode) currentNode).getJ3dNode());
162: } else if (editorPanel.getNodeName() == null
163: || editorPanel.getNodeName().length() == 0) {
164: currentNode.getContext().getNameControl().removeObject(
165: currentNode.getSceneName(),
166: currentNode.getNodeName(), // Old name
167: currentNode.getJ3dNode());
168: } else {
169: currentNode.getContext().getNameControl().renameObject(
170: currentNode.getSceneName(),
171: currentNode.getNodeName(), // Old name
172: name, // New name
173: currentNode.getJ3dNode());
174: }
175:
176: }
177:
178: /**
179: * Called by EditorFrame when cancel button is pressed
180: */
181: void resetChanges() {
182: editorPanel.setNodeName(currentNode.getNodeName());
183: frame.setNodeName(currentNode.getNodeName());
184: editorPanel.resetChanges();
185: }
186:
187: /**
188: * Edit the node if an editor is available
189: *
190: * Set the correct capability bits depending on tool mode
191: *
192: * Node can be live
193: */
194: public void editNode(SGObject node) {
195: frame.setNodeName(node.getNodeName());
196: frame.setSceneName(node.getSceneName());
197: frame.setEnabled(true);
198:
199: editorPanel = findEditorPanel(((SGNode) node).getJ3dNode());
200: if (editorPanel == null) {
201: editorPanel = noEditorPanel;
202: }
203:
204: if (node == currentNode)
205: return;
206:
207: currentNode = (SGNode) node;
208:
209: frame.capabilityStartEdit(currentNode); // Setup the capability Panel
210:
211: if (readOnly)
212: editorPanel.setReadOnly(true);
213:
214: editorPanel.startEdit(currentNode, frame);
215:
216: frame.showPanel(editorPanel);
217:
218: }
219:
220: /**
221: * Forgets any changes that are in progress
222: * Clears the editorPanel by showing emptyEditorPanel
223: */
224: public void clearEditorPanel() {
225: editorPanel = emptyEditorPanel;
226: frame.showPanel(editorPanel);
227: frame.setEnabled(false);
228: }
229:
230: /**
231: * Called when user finishes editing the currentNode
232: * This method is reponsible for applying any changes
233: * and reseting the capability bits of the node
234: */
235: public void editComplete() {
236: if (!readOnly && editorPanel.getUpdateRequired())
237: forceApplyOrReset();
238:
239: editorPanel.finishEdit();
240: frame.capabilityFinishEdit();
241: frame.showPanel(emptyEditorPanel);
242: frame.setEnabled(false);
243: editorPanel = emptyEditorPanel;
244:
245: currentNode = null;
246: }
247:
248: /**
249: * Returns true if a node is currently being edited
250: */
251: public boolean editInProgress() {
252: if (currentNode != null)
253: return true;
254: else
255: return false;
256: }
257:
258: /**
259: * Create the SGObjectExtraData structure for this node and populate with
260: * data if data exists, otherwise returns null
261: */
262: public SGObjectExtraData createSGObjectExtraData(
263: SceneGraphObject node,
264: org.jdesktop.j3dedit.scenegrapheditor.NodePersistance data) {
265: Class editorClass = (Class) editorClasses.get(node.getClass()
266: .getName());
267: SGObjectExtraData extraData = null;
268:
269: if (editorClass == null) {
270: System.err.println("ERROR - No EditorClass for " + node);
271: Thread.dumpStack();
272: return null;
273: }
274:
275: try {
276: java.lang.reflect.Method method = editorClass.getMethod(
277: "getExtraDataClass", (Class[]) null);
278: Class extraDataClass = (Class) method.invoke(editorClass,
279: (Object[]) null);
280:
281: extraData = (SGObjectExtraData) extraDataClass
282: .newInstance();
283: if (!extraData.readPersistanceData(data))
284: extraData = null;
285: } catch (Exception e) {
286: e.printStackTrace();
287: }
288:
289: return extraData;
290: }
291:
292: private NodeEditorPanel findEditorPanel(SceneGraphObject node) {
293: NodeEditorPanel ret;
294:
295: if (node == null)
296: return null;
297:
298: ret = (NodeEditorPanel) sharedPanels.get(node.getClass()
299: .getName());
300:
301: if (ret == null
302: && node instanceof com.sun.j3d.utils.geometry.Primitive) {
303: ret = (NodeEditorPanel) sharedPanels
304: .get("com.sun.j3d.utils.geometry.Primitive");
305: if (ret == null)
306: ret = createEditorPanel(node);
307: }
308:
309: if (ret == null)
310: ret = createEditorPanel(node);
311:
312: return ret;
313: }
314:
315: private NodeEditorPanel createEditorPanel(SceneGraphObject node) {
316: NodeEditorPanel ret = null;
317:
318: //System.out.println("Looking for "+node.getClass().getName() );
319:
320: Class editorClass = (Class) editorClasses.get(node.getClass()
321: .getName());
322:
323: //System.out.println("Found "+editorClass);
324:
325: if (editorClass == null) { // Check superclasses
326: editorClass = checkSuperclasses(node.getClass());
327: }
328:
329: try {
330: if (editorClass != null) {
331: ret = (NodeEditorPanel) editorClass.newInstance();
332: sharedPanels.put(node.getClass().getName(), ret);
333: return ret;
334: } else
335: return null;
336:
337: } catch (InstantiationException e) {
338: System.out.println("EditorManager: No such EditorPanel "
339: + editorClass);
340: e.printStackTrace();
341: return null;
342: } catch (IllegalAccessException ex) {
343: System.out.println("EditorManager: No such EditorPanel "
344: + editorClass);
345: ex.printStackTrace();
346: return null;
347: }
348:
349: }
350:
351: /**
352: * Look for editor classes suitable for editing <code>nodeClass</code>
353: * or one of it's superclasses
354: */
355: private Class checkSuperclasses(Class nodeClass) {
356: if (nodeClass == null)
357: return null;
358:
359: Class editorClass = (Class) editorClasses.get(nodeClass
360: .getName());
361:
362: if (editorClass == null)
363: editorClass = checkSuperclasses(nodeClass.getSuperclass());
364:
365: return editorClass;
366:
367: }
368:
369: private void forceApplyOrReset() {
370:
371: // Force apply
372: String message[] = { "Node Parameters have been changed", "",
373: "Apply changes ?", "" };
374:
375: int result = JOptionPane.showConfirmDialog(null, message,
376: "Apply Changes ?", JOptionPane.YES_NO_OPTION);
377:
378: switch (result) {
379: case JOptionPane.CLOSED_OPTION:
380: System.out.println("DIALOG CLOSED - Applying changes");
381: editorPanel.applyChanges();
382: break;
383: case JOptionPane.YES_OPTION:
384: editorPanel.applyChanges();
385: break;
386: case JOptionPane.NO_OPTION:
387: editorPanel.resetChanges();
388: break;
389: }
390: }
391: }
|