sceneexplorer.html 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]--><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="Asciidoctor 1.5.4"><title>The SceneExplorer</title><link rel="stylesheet" href="./asciidoctor.css">
  2. <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css">
  3. <link rel="stylesheet" href="./coderay-asciidoctor.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.css"></head><body class="article toc2 toc-left"><div id="header"><div id="toolbar"><a href="https://github.com/jMonkeyEngine/wiki/edit/master/src/docs/asciidoc/sdk/development/sceneexplorer.adoc"><i class="fa fa-pencil-square" aria-hidden="true"></i></a><a href="https://github.com/jMonkeyEngine/wiki/new/master/src/docs/asciidoc/sdk/development/"><i class="fa fa-plus-square" aria-hidden="true"></i></a><input dir="auto" style="position: relative; vertical-align: top;" spellcheck="false" autocomplete="off" class="searchbox__input aa-input" id="doc-search" name="search" placeholder="Search in the doc" required="required" type="search"><i class="fa fa-sort-down" aria-hidden="true"></i></div><h1>The SceneExplorer</h1><div class="details"><span class="author" id="author"></span><br><span id="revnumber">version ,</span> <span id="revdate">2016/03/17 20:48</span></div><div id="toc" class="toc2"><div id="toctitle">Table of Contents</div><ul class="sectlevel1"><li><a href="#adding-node-types-to-sceneexplorer">Adding Node types to SceneExplorer</a><ul class="sectlevel2"><li><a href="#spatial-example">Spatial Example</a></li><li><a href="#control-example">Control Example</a></li></ul></li><li><a href="#adding-items-to-the-add-and-tools-menus">Adding items to the add and tools menus</a><ul class="sectlevel2"><li><a href="#adding-using-a-wizard">Adding using a Wizard</a></li></ul></li></ul></div></div><div id="content"><div class="sect2"><h3 id="adding-node-types-to-sceneexplorer">Adding Node types to SceneExplorer</h3><div class="paragraph"><p>If your plugin brings in its own SceneGraph objects you can still have them work like any other SceneExplorer item, including its special properties.</p></div>
  4. <div class="paragraph"><p>If you want to support special properties of your objects that are not exposed by the SDK automatically, you will have to create your own class that extends org.openide.nodes.Node and implement the interface com.jme3.gde.core.sceneexplorer.nodes.AbstractSceneExplorerNode. Then you register that class by adding</p></div>
  5. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code>@org.openide.util.lookup.ServiceProvider(service=SceneExplorerNode.class)</code></pre></div></div>
  6. <div class="literalblock"><div class="content"><pre>above the body of your class. Thats all, your Spatial type will automatically be used and displayed in the SceneExplorer. Make sure you register a jar with the used classes in the plugin preferences under “wrapped libraries, otherwise the IDE cannot access those classes.</pre></div></div>
  7. <div class="paragraph"><p>AbstractSceneExplorerNode brings some other useful features you might want to include like automatic creation of properly threaded properties etc. JmeSpatial for example bases on it. A simple SceneExplorerNode example for an object extending Spatial would be JmeGeometry (see below). Editors for special variable types can be added using the SceneExplorerPropertyEditor interface, which can be registered as a ServiceProvider as well.</p></div>
  8. <div class="paragraph"><p>The SceneExplorerNode can be used for Spatial and Control type objects.</p></div>
  9. <div class="ulist"><ul><li><p><em>Add the “Nodes <abbr title="Application Programming Interface">API</abbr> and “Lookup <abbr title="Application Programming Interface">API</abbr> libraries to your project when you want to use this</em></p></li></ul></div>
  10. <div class="sect2"><h3 id="spatial-example">Spatial Example</h3><div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@org</span>.openide.util.lookup.ServiceProvider(service=SceneExplorerNode.class)
  11. <span class="directive">public</span> <span class="type">class</span> <span class="class">JmeGeometry</span> <span class="directive">extends</span> JmeSpatial {
  12. <span class="directive">private</span> <span class="directive">static</span> <span class="predefined-type">Image</span> smallImage =
  13. ImageUtilities.loadImage(<span class="string"><span class="delimiter">&quot;</span><span class="content">com/jme3/gde/core/sceneexplorer/nodes/icons/geometry.gif</span><span class="delimiter">&quot;</span></span>);
  14. <span class="directive">private</span> Geometry geom;
  15. <span class="directive">public</span> JmeGeometry() {
  16. }
  17. <span class="directive">public</span> JmeGeometry(Geometry spatial, SceneExplorerChildren children) {
  18. <span class="local-variable">super</span>(spatial, children);
  19. getLookupContents().add(spatial);
  20. <span class="local-variable">this</span>.geom = spatial;
  21. setName(spatial.getName());
  22. }
  23. <span class="annotation">@Override</span>
  24. <span class="directive">public</span> <span class="predefined-type">Image</span> getIcon(<span class="type">int</span> type) {
  25. <span class="keyword">return</span> smallImage;
  26. }
  27. <span class="annotation">@Override</span>
  28. <span class="directive">public</span> <span class="predefined-type">Image</span> getOpenedIcon(<span class="type">int</span> type) {
  29. <span class="keyword">return</span> smallImage;
  30. }
  31. <span class="annotation">@Override</span>
  32. <span class="directive">protected</span> Sheet createSheet() {
  33. Sheet sheet = <span class="local-variable">super</span>.createSheet();
  34. Sheet.Set set = Sheet.createPropertiesSet();
  35. set.setDisplayName(<span class="string"><span class="delimiter">&quot;</span><span class="content">Geometry</span><span class="delimiter">&quot;</span></span>);
  36. set.setName(Geometry.class.getName());
  37. Geometry obj = geom;<span class="comment">//getLookup().lookup(Geometry.class);</span>
  38. <span class="keyword">if</span> (obj == <span class="predefined-constant">null</span>) {
  39. <span class="keyword">return</span> sheet;
  40. }
  41. set.put(makeProperty(obj, <span class="type">int</span>.class, <span class="string"><span class="delimiter">&quot;</span><span class="content">getLodLevel</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">setLodLevel</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">Lod Level</span><span class="delimiter">&quot;</span></span>));
  42. set.put(makeProperty(obj, Material.class, <span class="string"><span class="delimiter">&quot;</span><span class="content">getMaterial</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">setMaterial</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">Material</span><span class="delimiter">&quot;</span></span>));
  43. set.put(makeProperty(obj, Mesh.class, <span class="string"><span class="delimiter">&quot;</span><span class="content">getMesh</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">Mesh</span><span class="delimiter">&quot;</span></span>));
  44. sheet.put(set);
  45. <span class="keyword">return</span> sheet;
  46. }
  47. <span class="directive">public</span> <span class="predefined-type">Class</span> getExplorerObjectClass() {
  48. <span class="keyword">return</span> Geometry.class;
  49. }
  50. <span class="directive">public</span> <span class="predefined-type">Class</span> getExplorerNodeClass() {
  51. <span class="keyword">return</span> JmeGeometry.class;
  52. }
  53. <span class="directive">public</span> org.openide.nodes.Node<span class="type">[]</span> createNodes(<span class="predefined-type">Object</span> key, <span class="predefined-type">Object</span> key2, <span class="type">boolean</span> readOnly) {
  54. SceneExplorerChildren children=<span class="keyword">new</span> SceneExplorerChildren((com.jme3.scene.Spatial)key);
  55. children.setReadOnly(readOnly);
  56. <span class="keyword">return</span> <span class="keyword">new</span> org.openide.nodes.Node<span class="type">[]</span>{<span class="keyword">new</span> JmeGeometry((Geometry) key, children).setReadOnly(readOnly)};
  57. }
  58. }</code></pre></div></div></div>
  59. <div class="sect2"><h3 id="control-example">Control Example</h3><div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@org</span>.openide.util.lookup.ServiceProvider(service=SceneExplorerNode.class)
  60. <span class="directive">public</span> <span class="type">class</span> <span class="class">JmeGhostControl</span> <span class="directive">extends</span> AbstractSceneExplorerNode {
  61. <span class="directive">private</span> <span class="directive">static</span> <span class="predefined-type">Image</span> smallImage =
  62. ImageUtilities.loadImage(<span class="string"><span class="delimiter">&quot;</span><span class="content">com/jme3/gde/core/sceneexplorer/nodes/icons/ghostcontrol.gif</span><span class="delimiter">&quot;</span></span>);
  63. <span class="directive">private</span> GhostControl control;
  64. <span class="directive">public</span> JmeGhostControl() {
  65. }
  66. <span class="directive">public</span> JmeGhostControl(GhostControl control, DataObject dataObject) {
  67. <span class="local-variable">super</span>(dataObject);
  68. getLookupContents().add(<span class="local-variable">this</span>);
  69. getLookupContents().add(control);
  70. <span class="local-variable">this</span>.control = control;
  71. setName(<span class="string"><span class="delimiter">&quot;</span><span class="content">GhostControl</span><span class="delimiter">&quot;</span></span>);
  72. }
  73. <span class="annotation">@Override</span>
  74. <span class="directive">public</span> <span class="predefined-type">Image</span> getIcon(<span class="type">int</span> type) {
  75. <span class="keyword">return</span> smallImage;
  76. }
  77. <span class="annotation">@Override</span>
  78. <span class="directive">public</span> <span class="predefined-type">Image</span> getOpenedIcon(<span class="type">int</span> type) {
  79. <span class="keyword">return</span> smallImage;
  80. }
  81. <span class="directive">protected</span> SystemAction<span class="type">[]</span> createActions() {
  82. <span class="keyword">return</span> <span class="keyword">new</span> SystemAction<span class="type">[]</span>{
  83. <span class="comment">// SystemAction.get(CopyAction.class),</span>
  84. <span class="comment">// SystemAction.get(CutAction.class),</span>
  85. <span class="comment">// SystemAction.get(PasteAction.class),</span>
  86. SystemAction.get(DeleteAction.class)
  87. };
  88. }
  89. <span class="annotation">@Override</span>
  90. <span class="directive">public</span> <span class="type">boolean</span> canDestroy() {
  91. <span class="keyword">return</span> !readOnly;
  92. }
  93. <span class="annotation">@Override</span>
  94. <span class="directive">public</span> <span class="type">void</span> destroy() <span class="directive">throws</span> <span class="exception">IOException</span> {
  95. <span class="local-variable">super</span>.destroy();
  96. <span class="directive">final</span> Spatial spat=getParentNode().getLookup().lookup(Spatial.class);
  97. <span class="keyword">try</span> {
  98. SceneApplication.getApplication().enqueue(<span class="keyword">new</span> <span class="predefined-type">Callable</span>&lt;<span class="predefined-type">Void</span>&gt;() {
  99. <span class="directive">public</span> <span class="predefined-type">Void</span> call() <span class="directive">throws</span> <span class="exception">Exception</span> {
  100. spat.removeControl(control);
  101. <span class="keyword">return</span> <span class="predefined-constant">null</span>;
  102. }
  103. }).get();
  104. ((AbstractSceneExplorerNode)getParentNode()).refresh(<span class="predefined-constant">true</span>);
  105. } <span class="keyword">catch</span> (<span class="exception">InterruptedException</span> ex) {
  106. Exceptions.printStackTrace(ex);
  107. } <span class="keyword">catch</span> (<span class="exception">ExecutionException</span> ex) {
  108. Exceptions.printStackTrace(ex);
  109. }
  110. }
  111. <span class="annotation">@Override</span>
  112. <span class="directive">protected</span> Sheet createSheet() {
  113. Sheet sheet = <span class="local-variable">super</span>.createSheet();
  114. Sheet.Set set = Sheet.createPropertiesSet();
  115. set.setDisplayName(<span class="string"><span class="delimiter">&quot;</span><span class="content">GhostControl</span><span class="delimiter">&quot;</span></span>);
  116. set.setName(GhostControl.class.getName());
  117. GhostControl obj = control;<span class="comment">//getLookup().lookup(Spatial.class);</span>
  118. <span class="keyword">if</span> (obj == <span class="predefined-constant">null</span>) {
  119. <span class="keyword">return</span> sheet;
  120. }
  121. set.put(makeProperty(obj, Vector3f.class, <span class="string"><span class="delimiter">&quot;</span><span class="content">getPhysicsLocation</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">setPhysicsLocation</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">Physics Location</span><span class="delimiter">&quot;</span></span>));
  122. set.put(makeProperty(obj, Quaternion.class, <span class="string"><span class="delimiter">&quot;</span><span class="content">getPhysicsRotation</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">setPhysicsRotation</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">Physics Rotation</span><span class="delimiter">&quot;</span></span>));
  123. set.put(makeProperty(obj, CollisionShape.class, <span class="string"><span class="delimiter">&quot;</span><span class="content">getCollisionShape</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">setCollisionShape</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">Collision Shape</span><span class="delimiter">&quot;</span></span>));
  124. set.put(makeProperty(obj, <span class="type">int</span>.class, <span class="string"><span class="delimiter">&quot;</span><span class="content">getCollisionGroup</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">setCollisionGroup</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">Collision Group</span><span class="delimiter">&quot;</span></span>));
  125. set.put(makeProperty(obj, <span class="type">int</span>.class, <span class="string"><span class="delimiter">&quot;</span><span class="content">getCollideWithGroups</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">setCollideWithGroups</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">Collide With Groups</span><span class="delimiter">&quot;</span></span>));
  126. sheet.put(set);
  127. <span class="keyword">return</span> sheet;
  128. }
  129. <span class="directive">public</span> <span class="predefined-type">Class</span> getExplorerObjectClass() {
  130. <span class="keyword">return</span> GhostControl.class;
  131. }
  132. <span class="directive">public</span> <span class="predefined-type">Class</span> getExplorerNodeClass() {
  133. <span class="keyword">return</span> JmeGhostControl.class;
  134. }
  135. <span class="directive">public</span> org.openide.nodes.Node<span class="type">[]</span> createNodes(<span class="predefined-type">Object</span> key, DataObject key2, <span class="type">boolean</span> cookie) {
  136. <span class="keyword">return</span> <span class="keyword">new</span> org.openide.nodes.Node<span class="type">[]</span>{<span class="keyword">new</span> JmeGhostControl((GhostControl) key, key2).setReadOnly(cookie)};
  137. }
  138. }</code></pre></div></div></div></div>
  139. <div class="sect2"><h3 id="adding-items-to-the-add-and-tools-menus">Adding items to the add and tools menus</h3><div class="paragraph"><p>For adding Spatials, Contols and for general tools theres premade abstract classes that you can use to extend the options. Undo/Redo is handled by the abstract class. AbstractNewSpatial*Wizard*Action allows you to show an AWT wizard before creating the Spatial. You can also just implement the base ServiceProvider class and return any kind of action (such as a wizard), in this case you have to handle the threading yourself!</p></div>
  140. <div class="admonitionblock important"><table><tr><td class="icon"><i class="fa icon-important" title="Important"></i></td><td class="content"><div class="paragraph"><p>Note that the classes you create are singletons which are used across multiple nodes and you should not store any data in local variables!</p></div></td></tr></table></div>
  141. <div class="paragraph"><p>To add a new Tool, create a new AbstractToolAction:</p></div>
  142. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@org</span>.openide.util.lookup.ServiceProvider(service = ToolAction.class)
  143. <span class="directive">public</span> <span class="type">class</span> <span class="class">GenerateTangentsTool</span> <span class="directive">extends</span> AbstractToolAction {
  144. <span class="directive">public</span> GenerateTangentsTool() {
  145. name = <span class="string"><span class="delimiter">&quot;</span><span class="content">Generate Tangents</span><span class="delimiter">&quot;</span></span>;
  146. }
  147. <span class="annotation">@Override</span>
  148. <span class="directive">protected</span> <span class="predefined-type">Object</span> doApplyTool(AbstractSceneExplorerNode rootNode) {
  149. Geometry geom = rootNode.getLookup().lookup(Geometry.class);
  150. Mesh mesh = geom.getMesh();
  151. <span class="keyword">if</span> (mesh != <span class="predefined-constant">null</span>) {
  152. TangentBinormalGenerator.generate(mesh);
  153. }
  154. <span class="keyword">return</span> geom;
  155. }
  156. <span class="annotation">@Override</span>
  157. <span class="directive">protected</span> <span class="type">void</span> doUndoTool(AbstractSceneExplorerNode rootNode, <span class="predefined-type">Object</span> undoObject) {
  158. Geometry geom = rootNode.getLookup().lookup(Geometry.class);
  159. Mesh mesh = geom.getMesh();
  160. <span class="keyword">if</span> (mesh != <span class="predefined-constant">null</span>) {
  161. mesh.clearBuffer(<span class="predefined-type">Type</span>.Tangent);
  162. }
  163. }
  164. <span class="directive">public</span> <span class="predefined-type">Class</span>&lt;?&gt; getNodeClass() {
  165. <span class="keyword">return</span> JmeGeometry.class;
  166. }
  167. }</code></pre></div></div>
  168. <div class="paragraph"><p>For a new Spatial or Control, use AbstractNewSpatialAction</p></div>
  169. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@org</span>.openide.util.lookup.ServiceProvider(service = NewSpatialAction.class)
  170. <span class="directive">public</span> <span class="type">class</span> <span class="class">NewSpecialSpatialAction</span> <span class="directive">extends</span> AbstractNewSpatialAction {
  171. <span class="directive">public</span> NewSpecialSpatialAction() {
  172. name = <span class="string"><span class="delimiter">&quot;</span><span class="content">Spatial</span><span class="delimiter">&quot;</span></span>;
  173. }
  174. <span class="annotation">@Override</span>
  175. <span class="directive">protected</span> Spatial doCreateSpatial(Node parent) {
  176. Spatial spatial=<span class="keyword">new</span> Node();
  177. <span class="keyword">return</span> spatial;
  178. }
  179. }</code></pre></div></div>
  180. <div class="paragraph"><p>or AbstractNewControlAction:</p></div>
  181. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@org</span>.openide.util.lookup.ServiceProvider(service = NewControlAction.class)
  182. <span class="directive">public</span> <span class="type">class</span> <span class="class">NewRigidBodyAction</span> <span class="directive">extends</span> AbstractNewControlAction {
  183. <span class="directive">public</span> NewRigidBodyAction() {
  184. name = <span class="string"><span class="delimiter">&quot;</span><span class="content">Static RigidBody</span><span class="delimiter">&quot;</span></span>;
  185. }
  186. <span class="annotation">@Override</span>
  187. <span class="directive">protected</span> <span class="predefined-type">Control</span> doCreateControl(Spatial spatial) {
  188. RigidBodyControl control = spatial.getControl(RigidBodyControl.class);
  189. <span class="keyword">if</span> (control != <span class="predefined-constant">null</span>) {
  190. spatial.removeControl(control);
  191. }
  192. Node parent = spatial.getParent();
  193. spatial.removeFromParent();
  194. control = <span class="keyword">new</span> RigidBodyControl(<span class="integer">0</span>);
  195. <span class="keyword">if</span> (parent != <span class="predefined-constant">null</span>) {
  196. parent.attachChild(spatial);
  197. }
  198. <span class="keyword">return</span> control;
  199. }
  200. }</code></pre></div></div>
  201. <div class="sect2"><h3 id="adding-using-a-wizard">Adding using a Wizard</h3><div class="paragraph"><p>You can create a new wizard using the wizard template in the SDK (New File→Module Development→Wizard). The Action that the template creates can easily be changed to one for adding a Control or Spatial or for applying a Tool. Note that we extend AbstractNewSpatial*Wizard*Action here.</p></div>
  202. <div class="paragraph"><p>A good example is the “Add SkyBox Wizard:</p></div>
  203. <div class="listingblock"><div class="content"><pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@org</span>.openide.util.lookup.ServiceProvider(service = NewSpatialAction.class)
  204. <span class="directive">public</span> <span class="type">class</span> <span class="class">AddSkyboxAction</span> <span class="directive">extends</span> AbstractNewSpatialWizardAction {
  205. <span class="directive">private</span> WizardDescriptor.Panel<span class="type">[]</span> panels;
  206. <span class="directive">public</span> AddSkyboxAction() {
  207. name = <span class="string"><span class="delimiter">&quot;</span><span class="content">Skybox..</span><span class="delimiter">&quot;</span></span>;
  208. }
  209. <span class="annotation">@Override</span>
  210. <span class="directive">protected</span> <span class="predefined-type">Object</span> showWizard(org.openide.nodes.Node node) {
  211. WizardDescriptor wizardDescriptor = <span class="keyword">new</span> WizardDescriptor(getPanels());
  212. wizardDescriptor.setTitleFormat(<span class="keyword">new</span> <span class="predefined-type">MessageFormat</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">{0}</span><span class="delimiter">&quot;</span></span>));
  213. wizardDescriptor.setTitle(<span class="string"><span class="delimiter">&quot;</span><span class="content">Skybox Wizard</span><span class="delimiter">&quot;</span></span>);
  214. <span class="predefined-type">Dialog</span> dialog = DialogDisplayer.getDefault().createDialog(wizardDescriptor);
  215. dialog.setVisible(<span class="predefined-constant">true</span>);
  216. dialog.toFront();
  217. <span class="type">boolean</span> cancelled = wizardDescriptor.getValue() != WizardDescriptor.FINISH_OPTION;
  218. <span class="keyword">if</span> (!cancelled) {
  219. <span class="keyword">return</span> wizardDescriptor;
  220. }
  221. <span class="keyword">return</span> <span class="predefined-constant">null</span>;
  222. }
  223. <span class="annotation">@Override</span>
  224. <span class="directive">protected</span> Spatial doCreateSpatial(Node parent, <span class="predefined-type">Object</span> properties) {
  225. <span class="keyword">if</span> (properties != <span class="predefined-constant">null</span>) {
  226. <span class="keyword">return</span> generateSkybox((WizardDescriptor) properties);
  227. }
  228. <span class="keyword">return</span> <span class="predefined-constant">null</span>;
  229. }
  230. <span class="directive">private</span> Spatial generateSkybox(WizardDescriptor wiz) {
  231. <span class="keyword">if</span> ((<span class="predefined-type">Boolean</span>) wiz.getProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">multipleTextures</span><span class="delimiter">&quot;</span></span>)) {
  232. Texture south = (Texture) wiz.getProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">textureSouth</span><span class="delimiter">&quot;</span></span>);
  233. Texture north = (Texture) wiz.getProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">textureNorth</span><span class="delimiter">&quot;</span></span>);
  234. Texture east = (Texture) wiz.getProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">textureEast</span><span class="delimiter">&quot;</span></span>);
  235. Texture west = (Texture) wiz.getProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">textureWest</span><span class="delimiter">&quot;</span></span>);
  236. Texture top = (Texture) wiz.getProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">textureTop</span><span class="delimiter">&quot;</span></span>);
  237. Texture bottom = (Texture) wiz.getProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">textureBottom</span><span class="delimiter">&quot;</span></span>);
  238. Vector3f normalScale = (Vector3f) wiz.getProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">normalScale</span><span class="delimiter">&quot;</span></span>);
  239. <span class="keyword">return</span> SkyFactory.createSky(pm, west, east, north, south, top, bottom, normalScale);
  240. } <span class="keyword">else</span> {
  241. Texture textureSingle = (Texture) wiz.getProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">textureSingle</span><span class="delimiter">&quot;</span></span>);
  242. Vector3f normalScale = (Vector3f) wiz.getProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">normalScale</span><span class="delimiter">&quot;</span></span>);
  243. <span class="type">boolean</span> useSpheremap = (<span class="predefined-type">Boolean</span>) wiz.getProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">useSpheremap</span><span class="delimiter">&quot;</span></span>);
  244. <span class="keyword">return</span> SkyFactory.createSky(pm, textureSingle, normalScale, useSpheremap);
  245. }
  246. }
  247. <span class="comment">/**
  248. * Initialize panels representing individual wizard's steps and sets
  249. * various properties for them influencing wizard appearance.
  250. */</span>
  251. <span class="directive">private</span> WizardDescriptor.Panel<span class="type">[]</span> getPanels() {
  252. <span class="keyword">if</span> (panels == <span class="predefined-constant">null</span>) {
  253. panels = <span class="keyword">new</span> WizardDescriptor.Panel<span class="type">[]</span>{
  254. <span class="keyword">new</span> SkyboxWizardPanel1(),
  255. <span class="keyword">new</span> SkyboxWizardPanel2()
  256. };
  257. <span class="predefined-type">String</span><span class="type">[]</span> steps = <span class="keyword">new</span> <span class="predefined-type">String</span>[panels.length];
  258. <span class="keyword">for</span> (<span class="type">int</span> i = <span class="integer">0</span>; i &lt; panels.length; i++) {
  259. <span class="predefined-type">Component</span> c = panels[i].getComponent();
  260. <span class="comment">// Default step name to component name of panel. Mainly useful</span>
  261. <span class="comment">// for getting the name of the target chooser to appear in the</span>
  262. <span class="comment">// list of steps.</span>
  263. steps[i] = c.getName();
  264. <span class="keyword">if</span> (c <span class="keyword">instanceof</span> <span class="predefined-type">JComponent</span>) { <span class="comment">// assume Swing components</span>
  265. <span class="predefined-type">JComponent</span> jc = (<span class="predefined-type">JComponent</span>) c;
  266. <span class="comment">// Sets step number of a component</span>
  267. <span class="comment">// TODO if using org.openide.dialogs &gt;= 7.8, can use WizardDescriptor.PROP_*:</span>
  268. jc.putClientProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">WizardPanel_contentSelectedIndex</span><span class="delimiter">&quot;</span></span>, <span class="keyword">new</span> <span class="predefined-type">Integer</span>(i));
  269. <span class="comment">// Sets steps names for a panel</span>
  270. jc.putClientProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">WizardPanel_contentData</span><span class="delimiter">&quot;</span></span>, steps);
  271. <span class="comment">// Turn on subtitle creation on each step</span>
  272. jc.putClientProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">WizardPanel_autoWizardStyle</span><span class="delimiter">&quot;</span></span>, <span class="predefined-type">Boolean</span>.TRUE);
  273. <span class="comment">// Show steps on the left side with the image on the background</span>
  274. jc.putClientProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">WizardPanel_contentDisplayed</span><span class="delimiter">&quot;</span></span>, <span class="predefined-type">Boolean</span>.TRUE);
  275. <span class="comment">// Turn on numbering of all steps</span>
  276. jc.putClientProperty(<span class="string"><span class="delimiter">&quot;</span><span class="content">WizardPanel_contentNumbered</span><span class="delimiter">&quot;</span></span>, <span class="predefined-type">Boolean</span>.TRUE);
  277. }
  278. }
  279. }
  280. <span class="keyword">return</span> panels;
  281. }
  282. }</code></pre></div></div>
  283. <div class="admonitionblock tip"><table><tr><td class="icon"><i class="fa icon-tip" title="Tip"></i></td><td class="content"><div class="paragraph"><p>The abstract spatial and control actions implement undo/redo automatically, for the ToolActions you have to implement it yourself.</p></div></td></tr></table></div></div></div></div><div id="footer"><div id="footer-text">Version <br>Last updated 2017-10-25 21:59:24 +00:00</div></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.js"></script><script>docsearch({
  284. apiKey: 'a736b6d93de805e26ec2f49b55013fbd',
  285. indexName: 'jmonkeyengine',
  286. inputSelector: '#doc-search',
  287. debug: false // Set debug to true if you want to inspect the dropdown
  288. });</script></body></html>