Selaa lähdekoodia

Created a ShaderNodeDefinition creation wizard

Rémy Bouquet 10 vuotta sitten
vanhempi
commit
f36cdfe0b9
15 muutettua tiedostoa jossa 1360 lisäystä ja 0 poistoa
  1. 115 0
      sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/SNDefDataObject.java
  2. 25 0
      sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/SNDefTemplate.j3sn
  3. 28 0
      sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/SNDefVisualElement.form
  4. 127 0
      sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/SNDefVisualElement.java
  5. 9 0
      sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/ShaderNodeSource
  6. 13 0
      sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/sNDef.html
  7. 10 0
      sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/wizard/Bundle.properties
  8. 158 0
      sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/wizard/SNDefVisualPanel1.form
  9. 146 0
      sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/wizard/SNDefVisualPanel1.java
  10. 141 0
      sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/wizard/SNDefVisualPanel2.form
  11. 209 0
      sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/wizard/SNDefVisualPanel2.java
  12. 222 0
      sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/wizard/SNDefWizardIterator.java
  13. 68 0
      sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/wizard/SNDefWizardPanel1.java
  14. 73 0
      sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/wizard/SNDefWizardPanel2.java
  15. 16 0
      sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/wizard/sNDef.html

+ 115 - 0
sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/SNDefDataObject.java

@@ -0,0 +1,115 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.gde.shadernodedefinition;
+
+import java.io.IOException;
+import org.netbeans.core.spi.multiview.MultiViewElement;
+import org.netbeans.core.spi.multiview.text.MultiViewEditorElement;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionReferences;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.MIMEResolver;
+import org.openide.loaders.DataObject;
+import org.openide.loaders.DataObjectExistsException;
+import org.openide.loaders.MultiDataObject;
+import org.openide.loaders.MultiFileLoader;
+import org.openide.util.Lookup;
+import org.openide.util.NbBundle.Messages;
+import org.openide.windows.TopComponent;
+
+@Messages({
+    "LBL_SNDef_LOADER=Files of SNDef"
+})
[email protected](
+        displayName = "#LBL_SNDef_LOADER",
+        mimeType = "text/x-j3sn",
+        extension = {"j3sn", "J3SN"}
+)
[email protected](
+        mimeType = "text/x-j3sn",
+        iconBase = "com/jme3/gde/materialdefinition/icons/node.png",
+        displayName = "#LBL_SNDef_LOADER",
+        position = 300
+)
+@ActionReferences({
+    @ActionReference(
+            path = "Loaders/text/x-j3sn/Actions",
+            id = @ActionID(category = "System", id = "org.openide.actions.OpenAction"),
+            position = 100,
+            separatorAfter = 200
+    ),
+    @ActionReference(
+            path = "Loaders/text/x-j3sn/Actions",
+            id = @ActionID(category = "Edit", id = "org.openide.actions.CutAction"),
+            position = 300
+    ),
+    @ActionReference(
+            path = "Loaders/text/x-j3sn/Actions",
+            id = @ActionID(category = "Edit", id = "org.openide.actions.CopyAction"),
+            position = 400,
+            separatorAfter = 500
+    ),
+    @ActionReference(
+            path = "Loaders/text/x-j3sn/Actions",
+            id = @ActionID(category = "Edit", id = "org.openide.actions.DeleteAction"),
+            position = 600
+    ),
+    @ActionReference(
+            path = "Loaders/text/x-j3sn/Actions",
+            id = @ActionID(category = "System", id = "org.openide.actions.RenameAction"),
+            position = 700,
+            separatorAfter = 800
+    ),
+    @ActionReference(
+            path = "Loaders/text/x-j3sn/Actions",
+            id = @ActionID(category = "System", id = "org.openide.actions.SaveAsTemplateAction"),
+            position = 900,
+            separatorAfter = 1000
+    ),
+    @ActionReference(
+            path = "Loaders/text/x-j3sn/Actions",
+            id = @ActionID(category = "System", id = "org.openide.actions.FileSystemAction"),
+            position = 1100,
+            separatorAfter = 1200
+    ),
+    @ActionReference(
+            path = "Loaders/text/x-j3sn/Actions",
+            id = @ActionID(category = "System", id = "org.openide.actions.ToolsAction"),
+            position = 1300
+    ),
+    @ActionReference(
+            path = "Loaders/text/x-j3sn/Actions",
+            id = @ActionID(category = "System", id = "org.openide.actions.PropertiesAction"),
+            position = 1400
+    )
+})
+public class SNDefDataObject extends MultiDataObject {
+
+    public SNDefDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException {
+        super(pf, loader);
+        registerEditor("text/x-j3sn", true);
+    }
+
+    @Override
+    protected int associateLookup() {
+        return 1;
+    }
+
+    @MultiViewElement.Registration(
+            displayName = "#LBL_SNDef_EDITOR",
+            iconBase = "com/jme3/gde/materialdefinition/icons/node.png",
+            mimeType = "text/x-j3sn",
+            persistenceType = TopComponent.PERSISTENCE_ONLY_OPENED,
+            preferredID = "SNDef",
+            position = 1000
+    )
+    @Messages("LBL_SNDef_EDITOR=Source")
+    public static MultiViewEditorElement createEditor(Lookup lkp) {
+        return new MultiViewEditorElement(lkp);
+    }
+
+}

+ 25 - 0
sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/SNDefTemplate.j3sn

@@ -0,0 +1,25 @@
+ShaderNodeDefinitions{ 
+    ShaderNodeDefinition ${defName} {      
+        Type: ${defType}
+        Shader GLSL100: ${shaderSnippet}
+        Documentation{
+            ${description}            
+            <#list inputParams as param>                
+            @input ${param[0]} ${param[1]} ${param[2]}
+            </#list>
+            <#list outputParams as param>                
+            @output ${param[0]} ${param[1]} ${param[2]}
+            </#list>            
+        }
+        Input {
+            <#list inputParams as param>                
+            ${param[0]} ${param[1]}
+            </#list>            
+        }
+        Output {
+            <#list outputParams as param>                
+             ${param[0]} ${param[1]}
+            </#list>                        
+        }
+    }
+}

+ 28 - 0
sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/SNDefVisualElement.form

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <EmptySpace min="0" pref="400" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <EmptySpace min="0" pref="300" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+</Form>

+ 127 - 0
sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/SNDefVisualElement.java

@@ -0,0 +1,127 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.gde.shadernodedefinition;
+
+import javax.swing.Action;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.JToolBar;
+import org.netbeans.core.spi.multiview.CloseOperationState;
+import org.netbeans.core.spi.multiview.MultiViewElement;
+import org.netbeans.core.spi.multiview.MultiViewElementCallback;
+import org.openide.awt.UndoRedo;
+import org.openide.util.Lookup;
+import org.openide.util.NbBundle.Messages;
+import org.openide.windows.TopComponent;
+
[email protected](
+        displayName = "#LBL_SNDef_VISUAL",
+        iconBase = "com/jme3/gde/materialdefinition/icons/node.png",
+        mimeType = "text/x-j3sn",
+        persistenceType = TopComponent.PERSISTENCE_NEVER,
+        preferredID = "SNDefVisual",
+        position = 2000
+)
+@Messages("LBL_SNDef_VISUAL=Visual")
+public final class SNDefVisualElement extends JPanel implements MultiViewElement {
+
+    private SNDefDataObject obj;
+    private JToolBar toolbar = new JToolBar();
+    private transient MultiViewElementCallback callback;
+
+    public SNDefVisualElement(Lookup lkp) {
+        obj = lkp.lookup(SNDefDataObject.class);
+        assert obj != null;
+        initComponents();
+    }
+
+    @Override
+    public String getName() {
+        return "SNDefVisualElement";
+    }
+
+    /**
+     * This method is called from within the constructor to initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is always
+     * regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGap(0, 400, Short.MAX_VALUE)
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGap(0, 300, Short.MAX_VALUE)
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    // End of variables declaration//GEN-END:variables
+    @Override
+    public JComponent getVisualRepresentation() {
+        return this;
+    }
+
+    @Override
+    public JComponent getToolbarRepresentation() {
+        return toolbar;
+    }
+
+    @Override
+    public Action[] getActions() {
+        return new Action[0];
+    }
+
+    @Override
+    public Lookup getLookup() {
+        return obj.getLookup();
+    }
+
+    @Override
+    public void componentOpened() {
+    }
+
+    @Override
+    public void componentClosed() {
+    }
+
+    @Override
+    public void componentShowing() {
+    }
+
+    @Override
+    public void componentHidden() {
+    }
+
+    @Override
+    public void componentActivated() {
+    }
+
+    @Override
+    public void componentDeactivated() {
+    }
+
+    @Override
+    public UndoRedo getUndoRedo() {
+        return UndoRedo.NONE;
+    }
+
+    @Override
+    public void setMultiViewCallback(MultiViewElementCallback callback) {
+        this.callback = callback;
+    }
+
+    @Override
+    public CloseOperationState canCloseElement() {
+        return CloseOperationState.STATE_OK;
+    }
+
+}

+ 9 - 0
sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/ShaderNodeSource

@@ -0,0 +1,9 @@
+<#list inputParams as param>                
+//@input ${param[0]} ${param[1]} ${param[2]}
+</#list>
+<#list outputParams as param>                
+//@output ${param[0]} ${param[1]} ${param[2]}
+</#list>            
+void main(){
+    //insert glsl code here
+}

+ 13 - 0
sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/sNDef.html

@@ -0,0 +1,13 @@
+<!--
+To change this license header, choose License Headers in Project Properties.
+To change this template file, choose Tools | Templates
+and open the template in the editor.
+-->
+<html>
+    <head>
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>        
+        A new Shader Node Definition file that can be instantiated as a Shader Node in the Shader Node editor
+    </body>
+</html>

+ 10 - 0
sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/wizard/Bundle.properties

@@ -0,0 +1,10 @@
+SNDefVisualPanel1.jLabel1.text=Definition Name
+SNDefVisualPanel1.defNameTextField.toolTipText=
+SNDefVisualPanel1.defNameTextField.text=
+SNDefVisualPanel1.jLabel2.text=Shader type
+SNDefVisualPanel1.jPanel2.border.title=Description
+SNDefVisualPanel2.addButton.text=
+SNDefVisualPanel2.titleLabel.text=Inputs
+SNDefVisualPanel2.addButton.toolTipText=Add an entry
+SNDefVisualPanel2.delButton.toolTipText=Delete an entry
+SNDefVisualPanel2.delButton.text=

+ 158 - 0
sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/wizard/SNDefVisualPanel1.form

@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Component id="jPanel1" alignment="0" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Component id="jPanel1" alignment="0" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Container class="javax.swing.JPanel" name="jPanel1">
+
+      <Layout>
+        <DimensionLayout dim="0">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" alignment="1" attributes="0">
+                  <Group type="103" groupAlignment="1" attributes="0">
+                      <Group type="102" attributes="0">
+                          <EmptySpace max="-2" attributes="0"/>
+                          <Component id="jPanel2" max="32767" attributes="0"/>
+                      </Group>
+                      <Group type="102" attributes="0">
+                          <EmptySpace min="-2" pref="14" max="-2" attributes="0"/>
+                          <Group type="103" groupAlignment="1" attributes="0">
+                              <Component id="jLabel2" min="-2" max="-2" attributes="0"/>
+                              <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
+                          </Group>
+                          <EmptySpace max="-2" attributes="0"/>
+                          <Group type="103" groupAlignment="0" attributes="0">
+                              <Component id="defNameTextField" max="32767" attributes="0"/>
+                              <Component id="shaderTypeCB" max="32767" attributes="0"/>
+                          </Group>
+                      </Group>
+                  </Group>
+                  <EmptySpace max="-2" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+        <DimensionLayout dim="1">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" alignment="0" attributes="0">
+                  <EmptySpace min="-2" pref="40" max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="3" attributes="0">
+                      <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
+                      <Component id="defNameTextField" alignment="3" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="3" attributes="0">
+                      <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/>
+                      <Component id="shaderTypeCB" alignment="3" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Component id="jPanel2" max="32767" attributes="0"/>
+                  <EmptySpace max="-2" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+      </Layout>
+      <SubComponents>
+        <Component class="javax.swing.JLabel" name="jLabel1">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/shadernodedefinition/wizard/Bundle.properties" key="SNDefVisualPanel1.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JTextField" name="defNameTextField">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/shadernodedefinition/wizard/Bundle.properties" key="SNDefVisualPanel1.defNameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/shadernodedefinition/wizard/Bundle.properties" key="SNDefVisualPanel1.defNameTextField.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="jLabel2">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/shadernodedefinition/wizard/Bundle.properties" key="SNDefVisualPanel1.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JComboBox" name="shaderTypeCB">
+          <Properties>
+            <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
+              <StringArray count="4">
+                <StringItem index="0" value="Item 1"/>
+                <StringItem index="1" value="Item 2"/>
+                <StringItem index="2" value="Item 3"/>
+                <StringItem index="3" value="Item 4"/>
+              </StringArray>
+            </Property>
+          </Properties>
+        </Component>
+        <Container class="javax.swing.JPanel" name="jPanel2">
+          <Properties>
+            <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+              <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
+                <TitledBorder title="Description">
+                  <ResourceString PropertyName="titleX" bundle="com/jme3/gde/shadernodedefinition/wizard/Bundle.properties" key="SNDefVisualPanel1.jPanel2.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+                </TitledBorder>
+              </Border>
+            </Property>
+          </Properties>
+
+          <Layout>
+            <DimensionLayout dim="0">
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Component id="jScrollPane1" alignment="0" pref="376" max="32767" attributes="0"/>
+              </Group>
+            </DimensionLayout>
+            <DimensionLayout dim="1">
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Component id="jScrollPane1" alignment="0" pref="157" max="32767" attributes="0"/>
+              </Group>
+            </DimensionLayout>
+          </Layout>
+          <SubComponents>
+            <Container class="javax.swing.JScrollPane" name="jScrollPane1">
+              <AuxValues>
+                <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
+              </AuxValues>
+
+              <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+              <SubComponents>
+                <Component class="javax.swing.JTextArea" name="descriptionTextArea">
+                  <Properties>
+                    <Property name="columns" type="int" value="20"/>
+                    <Property name="rows" type="int" value="5"/>
+                  </Properties>
+                </Component>
+              </SubComponents>
+            </Container>
+          </SubComponents>
+        </Container>
+      </SubComponents>
+    </Container>
+  </SubComponents>
+</Form>

+ 146 - 0
sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/wizard/SNDefVisualPanel1.java

@@ -0,0 +1,146 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.gde.shadernodedefinition.wizard;
+
+import com.jme3.shader.Shader;
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.JPanel;
+
+public final class SNDefVisualPanel1 extends JPanel {
+
+   
+    /**
+     * Creates new form SNDefVisualPanel1
+     */
+    public SNDefVisualPanel1() {
+        initComponents();
+        DefaultComboBoxModel<String> model = new DefaultComboBoxModel<String>();
+        for (Shader.ShaderType shaderType : Shader.ShaderType.values()) {
+            model.addElement(shaderType.name());
+        }
+        shaderTypeCB.setModel(model);
+    }
+
+    @Override
+    public String getName() {
+        return "Shader node informations";
+    }
+
+    public String getDefName(){
+        return defNameTextField.getText();
+    }
+    
+    public String getDefType(){
+        return (String)shaderTypeCB.getModel().getSelectedItem();
+    }
+    
+    public String getDefDescription(){
+        return descriptionTextArea.getText();
+    }
+    
+    
+    /**
+     * This method is called from within the constructor to initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is always
+     * regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        jPanel1 = new javax.swing.JPanel();
+        jLabel1 = new javax.swing.JLabel();
+        defNameTextField = new javax.swing.JTextField();
+        jLabel2 = new javax.swing.JLabel();
+        shaderTypeCB = new javax.swing.JComboBox();
+        jPanel2 = new javax.swing.JPanel();
+        jScrollPane1 = new javax.swing.JScrollPane();
+        descriptionTextArea = new javax.swing.JTextArea();
+
+        org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(SNDefVisualPanel1.class, "SNDefVisualPanel1.jLabel1.text")); // NOI18N
+
+        defNameTextField.setText(org.openide.util.NbBundle.getMessage(SNDefVisualPanel1.class, "SNDefVisualPanel1.defNameTextField.text")); // NOI18N
+        defNameTextField.setToolTipText(org.openide.util.NbBundle.getMessage(SNDefVisualPanel1.class, "SNDefVisualPanel1.defNameTextField.toolTipText")); // NOI18N
+
+        org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(SNDefVisualPanel1.class, "SNDefVisualPanel1.jLabel2.text")); // NOI18N
+
+        shaderTypeCB.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
+
+        jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(SNDefVisualPanel1.class, "SNDefVisualPanel1.jPanel2.border.title"))); // NOI18N
+
+        descriptionTextArea.setColumns(20);
+        descriptionTextArea.setRows(5);
+        jScrollPane1.setViewportView(descriptionTextArea);
+
+        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
+        jPanel2.setLayout(jPanel2Layout);
+        jPanel2Layout.setHorizontalGroup(
+            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 376, Short.MAX_VALUE)
+        );
+        jPanel2Layout.setVerticalGroup(
+            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 157, Short.MAX_VALUE)
+        );
+
+        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
+        jPanel1.setLayout(jPanel1Layout);
+        jPanel1Layout.setHorizontalGroup(
+            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
+                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+                    .addGroup(jPanel1Layout.createSequentialGroup()
+                        .addContainerGap()
+                        .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+                    .addGroup(jPanel1Layout.createSequentialGroup()
+                        .addGap(14, 14, 14)
+                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+                            .addComponent(jLabel2)
+                            .addComponent(jLabel1))
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                            .addComponent(defNameTextField)
+                            .addComponent(shaderTypeCB, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
+                .addContainerGap())
+        );
+        jPanel1Layout.setVerticalGroup(
+            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(jPanel1Layout.createSequentialGroup()
+                .addGap(40, 40, 40)
+                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(jLabel1)
+                    .addComponent(defNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(jLabel2)
+                    .addComponent(shaderTypeCB, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                .addContainerGap())
+        );
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JTextField defNameTextField;
+    private javax.swing.JTextArea descriptionTextArea;
+    private javax.swing.JLabel jLabel1;
+    private javax.swing.JLabel jLabel2;
+    private javax.swing.JPanel jPanel1;
+    private javax.swing.JPanel jPanel2;
+    private javax.swing.JScrollPane jScrollPane1;
+    private javax.swing.JComboBox shaderTypeCB;
+    // End of variables declaration//GEN-END:variables
+}

+ 141 - 0
sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/wizard/SNDefVisualPanel2.form

@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Component id="jPanel1" alignment="0" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Component id="jPanel1" alignment="0" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Container class="javax.swing.JPanel" name="jPanel1">
+
+      <Layout>
+        <DimensionLayout dim="0">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" attributes="0">
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="0" attributes="0">
+                      <Component id="jScrollPane1" pref="388" max="32767" attributes="0"/>
+                      <Group type="102" attributes="0">
+                          <Component id="titleLabel" min="-2" max="-2" attributes="0"/>
+                          <EmptySpace max="32767" attributes="0"/>
+                          <Component id="addButton" min="-2" max="-2" attributes="0"/>
+                          <EmptySpace max="-2" attributes="0"/>
+                          <Component id="delButton" min="-2" max="-2" attributes="0"/>
+                      </Group>
+                  </Group>
+                  <EmptySpace max="-2" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+        <DimensionLayout dim="1">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" alignment="1" attributes="0">
+                  <Group type="103" groupAlignment="0" attributes="0">
+                      <Group type="102" attributes="0">
+                          <EmptySpace max="32767" attributes="0"/>
+                          <Component id="titleLabel" min="-2" max="-2" attributes="0"/>
+                      </Group>
+                      <Group type="102" alignment="1" attributes="0">
+                          <Component id="delButton" min="-2" max="-2" attributes="0"/>
+                          <EmptySpace min="0" pref="0" max="32767" attributes="0"/>
+                      </Group>
+                      <Group type="102" alignment="0" attributes="0">
+                          <EmptySpace min="0" pref="0" max="32767" attributes="0"/>
+                          <Component id="addButton" min="-2" max="-2" attributes="0"/>
+                      </Group>
+                  </Group>
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Component id="jScrollPane1" min="-2" pref="278" max="-2" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+      </Layout>
+      <SubComponents>
+        <Container class="javax.swing.JScrollPane" name="jScrollPane1">
+          <AuxValues>
+            <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
+          </AuxValues>
+
+          <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+          <SubComponents>
+            <Component class="javax.swing.JTable" name="varTable">
+              <Properties>
+                <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
+                  <Color blue="ee" green="ee" id="Label.background" palette="3" red="ee" type="palette"/>
+                </Property>
+                <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
+                  <Table columnCount="3" rowCount="0">
+                    <Column editable="true" title="Type" type="java.lang.String"/>
+                    <Column editable="true" title="Name" type="java.lang.String"/>
+                    <Column editable="true" title="Description" type="java.lang.String"/>
+                  </Table>
+                </Property>
+              </Properties>
+            </Component>
+          </SubComponents>
+        </Container>
+        <Component class="javax.swing.JLabel" name="titleLabel">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/shadernodedefinition/wizard/Bundle.properties" key="SNDefVisualPanel2.titleLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JButton" name="addButton">
+          <Properties>
+            <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
+              <Image iconType="3" name="/com/jme3/gde/materials/multiview/widgets/icons/picture_add.png"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/shadernodedefinition/wizard/Bundle.properties" key="SNDefVisualPanel2.addButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/shadernodedefinition/wizard/Bundle.properties" key="SNDefVisualPanel2.addButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="alignmentX" type="float" value="0.5"/>
+          </Properties>
+          <Events>
+            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="addButtonActionPerformed"/>
+          </Events>
+        </Component>
+        <Component class="javax.swing.JButton" name="delButton">
+          <Properties>
+            <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
+              <Image iconType="3" name="/com/jme3/gde/materials/multiview/widgets/icons/picture_delete.png"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/shadernodedefinition/wizard/Bundle.properties" key="SNDefVisualPanel2.delButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/shadernodedefinition/wizard/Bundle.properties" key="SNDefVisualPanel2.delButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="alignmentX" type="float" value="0.5"/>
+          </Properties>
+          <Events>
+            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="delButtonActionPerformed"/>
+          </Events>
+        </Component>
+      </SubComponents>
+    </Container>
+  </SubComponents>
+</Form>

+ 209 - 0
sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/wizard/SNDefVisualPanel2.java

@@ -0,0 +1,209 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.gde.shadernodedefinition.wizard;
+
+import java.awt.EventQueue;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.table.DefaultTableModel;
+
+public final class SNDefVisualPanel2 extends JPanel {
+
+    private final Object[] emptyObj = {"", "", ""};
+    private final String type;
+
+    /**
+     * Creates new form SNDefVisualPanel2
+     */
+    public SNDefVisualPanel2(String type) {
+        initComponents();
+        this.type = type;
+        titleLabel.setText(type);
+        varTable.getColumnModel().getSelectionModel().addListSelectionListener(new ExploreSelectionListener());
+    }
+
+    @Override
+    public String getName() {
+        return type;
+    }
+
+    public String[][] getData() {
+
+        DefaultTableModel model = (DefaultTableModel) varTable.getModel();
+        String[][] data = new String[model.getRowCount()][3];
+        for (int i = 0; i < model.getRowCount(); i++) {
+            data[i][0] = (String) model.getValueAt(i, 0);
+            data[i][1] = (String) model.getValueAt(i, 1);
+            data[i][2] = (String) model.getValueAt(i, 2);
+        }
+
+        return data;
+    }
+
+    // Add this class to the body of MyTable class.
+    private class ExploreSelectionListener implements ListSelectionListener {
+
+        public void valueChanged(ListSelectionEvent e) {
+            if (!e.getValueIsAdjusting()) {              
+                int row = varTable.getSelectedRow();
+                int col = varTable.getSelectedColumn();
+                // Make sure we start with legal values.
+                if (col < 0) {
+                    col = 0;
+                }
+                if (row < 0) {
+                    row = 0;
+                }
+                // Find the next editable cell.
+                while (!varTable.isCellEditable(row, col)) {
+                    col++;
+                    if (col > varTable.getColumnCount() - 1) {
+                        col = 1;
+                        row = (row == varTable.getRowCount() - 1) ? 1 : row + 1;
+                    }
+                }
+                // Select the cell in the table.
+                final int r = row, c = col;
+                EventQueue.invokeLater(new Runnable() {
+                    public void run() {
+                        varTable.changeSelection(r, c, false, false);
+                    }
+                });
+                // Edit.
+                if (varTable.isCellEditable(row, col)) {
+                    varTable.editCellAt(row, col);
+                    ((JTextField) varTable.getEditorComponent()).selectAll();
+                    varTable.getEditorComponent().requestFocusInWindow();
+                }
+            }
+        }
+    }
+
+    /**
+     * This method is called from within the constructor to initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is always
+     * regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        jPanel1 = new javax.swing.JPanel();
+        jScrollPane1 = new javax.swing.JScrollPane();
+        varTable = new javax.swing.JTable();
+        titleLabel = new javax.swing.JLabel();
+        addButton = new javax.swing.JButton();
+        delButton = new javax.swing.JButton();
+
+        varTable.setBackground(javax.swing.UIManager.getDefaults().getColor("Label.background"));
+        varTable.setModel(new javax.swing.table.DefaultTableModel(
+            new Object [][] {
+
+            },
+            new String [] {
+                "Type", "Name", "Description"
+            }
+        ) {
+            Class[] types = new Class [] {
+                java.lang.String.class, java.lang.String.class, java.lang.String.class
+            };
+
+            public Class getColumnClass(int columnIndex) {
+                return types [columnIndex];
+            }
+        });
+        jScrollPane1.setViewportView(varTable);
+
+        org.openide.awt.Mnemonics.setLocalizedText(titleLabel, org.openide.util.NbBundle.getMessage(SNDefVisualPanel2.class, "SNDefVisualPanel2.titleLabel.text")); // NOI18N
+
+        addButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/jme3/gde/materials/multiview/widgets/icons/picture_add.png"))); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(addButton, org.openide.util.NbBundle.getMessage(SNDefVisualPanel2.class, "SNDefVisualPanel2.addButton.text")); // NOI18N
+        addButton.setToolTipText(org.openide.util.NbBundle.getMessage(SNDefVisualPanel2.class, "SNDefVisualPanel2.addButton.toolTipText")); // NOI18N
+        addButton.setAlignmentX(0.5F);
+        addButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                addButtonActionPerformed(evt);
+            }
+        });
+
+        delButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/jme3/gde/materials/multiview/widgets/icons/picture_delete.png"))); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(delButton, org.openide.util.NbBundle.getMessage(SNDefVisualPanel2.class, "SNDefVisualPanel2.delButton.text")); // NOI18N
+        delButton.setToolTipText(org.openide.util.NbBundle.getMessage(SNDefVisualPanel2.class, "SNDefVisualPanel2.delButton.toolTipText")); // NOI18N
+        delButton.setAlignmentX(0.5F);
+        delButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                delButtonActionPerformed(evt);
+            }
+        });
+
+        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
+        jPanel1.setLayout(jPanel1Layout);
+        jPanel1Layout.setHorizontalGroup(
+            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(jPanel1Layout.createSequentialGroup()
+                .addContainerGap()
+                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 388, Short.MAX_VALUE)
+                    .addGroup(jPanel1Layout.createSequentialGroup()
+                        .addComponent(titleLabel)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                        .addComponent(addButton)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                        .addComponent(delButton)))
+                .addContainerGap())
+        );
+        jPanel1Layout.setVerticalGroup(
+            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
+                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(jPanel1Layout.createSequentialGroup()
+                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                        .addComponent(titleLabel))
+                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
+                        .addComponent(delButton)
+                        .addGap(0, 0, Short.MAX_VALUE))
+                    .addGroup(jPanel1Layout.createSequentialGroup()
+                        .addGap(0, 0, Short.MAX_VALUE)
+                        .addComponent(addButton)))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 278, javax.swing.GroupLayout.PREFERRED_SIZE))
+        );
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+    private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addButtonActionPerformed
+        DefaultTableModel model = (DefaultTableModel) varTable.getModel();
+        model.addRow(emptyObj);
+    }//GEN-LAST:event_addButtonActionPerformed
+
+    private void delButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_delButtonActionPerformed
+        DefaultTableModel model = (DefaultTableModel) varTable.getModel();
+        int selRow = varTable.getSelectedRow();
+        if (selRow >= 0) {
+            model.removeRow(selRow);
+        }
+    }//GEN-LAST:event_delButtonActionPerformed
+
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JButton addButton;
+    private javax.swing.JButton delButton;
+    private javax.swing.JPanel jPanel1;
+    private javax.swing.JScrollPane jScrollPane1;
+    private javax.swing.JLabel titleLabel;
+    private javax.swing.JTable varTable;
+    // End of variables declaration//GEN-END:variables
+}

+ 222 - 0
sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/wizard/SNDefWizardIterator.java

@@ -0,0 +1,222 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.gde.shadernodedefinition.wizard;
+
+import com.jme3.gde.core.assets.ProjectAssetManager;
+import java.awt.Component;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import javax.swing.JComponent;
+import javax.swing.event.ChangeListener;
+import javax.xml.transform.Templates;
+import org.netbeans.api.project.Project;
+import org.netbeans.api.project.ProjectUtils;
+import org.netbeans.api.project.SourceGroup;
+import org.netbeans.api.project.Sources;
+import org.netbeans.api.templates.TemplateRegistration;
+import org.netbeans.api.templates.TemplateRegistrations;
+import org.netbeans.spi.project.ui.templates.support.Templates;
+import org.openide.WizardDescriptor;
+import org.openide.filesystems.FileObject;
+import org.openide.loaders.DataFolder;
+import org.openide.loaders.DataObject;
+import org.openide.util.NbBundle.Messages;
+
+// TODO define position attribute
+@TemplateRegistrations({
+@TemplateRegistration(folder = "Material", content = "../SNDefTemplate.j3sn", displayName = "#SNDefWizardIterator_displayName", iconBase = "com/jme3/gde/materialdefinition/icons/node.png", description = "../sNDef.html", scriptEngine = "freemarker"),
+@TemplateRegistration(folder = "Material", content = "../ShaderNodeSource", scriptEngine = "freemarker")
+})
+@Messages("SNDefWizardIterator_displayName=Shader Node Definition")
+public final class SNDefWizardIterator implements WizardDescriptor.InstantiatingIterator<WizardDescriptor> {
+
+    private int index;
+
+    private WizardDescriptor wizard;
+    private List<WizardDescriptor.Panel<WizardDescriptor>> panels;
+
+    private List<WizardDescriptor.Panel<WizardDescriptor>> getPanels() {
+        if (panels == null) {
+            panels = new ArrayList<WizardDescriptor.Panel<WizardDescriptor>>();
+            // Change to default new file panel and add our panel at bottom
+            Project p = Templates.getProject(wizard);
+            SourceGroup[] groups = ProjectUtils.getSources(p).getSourceGroups(Sources.TYPE_GENERIC);
+
+            // SimpleTargetChooser is the default new file panel,
+            // Add our panel at the bottom
+            WizardDescriptor.Panel<WizardDescriptor> advNewFilePanel = Templates.buildSimpleTargetChooser(p, groups).create();
+            panels.add(advNewFilePanel);
+            panels.add(new SNDefWizardPanel1());
+            panels.add(new SNDefWizardPanel2("Inputs"));
+            panels.add(new SNDefWizardPanel2("Outputs"));
+            String[] steps = createSteps();
+            for (int i = 0; i < panels.size(); i++) {
+                Component c = panels.get(i).getComponent();
+                if (steps[i] == null) {
+                    // Default step name to component name of panel. Mainly
+                    // useful for getting the name of the target chooser to
+                    // appear in the list of steps.
+                    steps[i] = c.getName();
+                }
+                if (c instanceof JComponent) { // assume Swing components
+                    JComponent jc = (JComponent) c;
+                    jc.putClientProperty(WizardDescriptor.PROP_CONTENT_SELECTED_INDEX, i);
+                    jc.putClientProperty(WizardDescriptor.PROP_CONTENT_DATA, steps);
+                    jc.putClientProperty(WizardDescriptor.PROP_AUTO_WIZARD_STYLE, true);
+                    jc.putClientProperty(WizardDescriptor.PROP_CONTENT_DISPLAYED, true);
+                    jc.putClientProperty(WizardDescriptor.PROP_CONTENT_NUMBERED, true);
+                }
+            }
+        }
+        return panels;
+    }
+
+    @Override
+    public Set<?> instantiate() throws IOException {
+
+        FileObject createdFile = null;
+
+        // Read Title from wizard 
+        // String HtmlTitle = (String) wizard.getProperty(SNDefWizardPanel1.TITLE);
+        // FreeMarker Template will get its variables from HashMap.
+        // HashMap key is the variable name.
+        SNDefVisualPanel1 panel1 = ((SNDefWizardPanel1) panels.get(1)).getComponent();
+        SNDefVisualPanel2 panel2 = ((SNDefWizardPanel2) panels.get(2)).getComponent();
+        SNDefVisualPanel2 panel3 = ((SNDefWizardPanel2) panels.get(3)).getComponent();
+
+        Map args = new HashMap();
+        args.put("defName", panel1.getDefName());
+        args.put("defType", panel1.getDefType());
+        args.put("description", panel1.getDefDescription());
+        args.put("inputParams", panel2.getData());
+        args.put("outputParams", panel3.getData());
+
+        //Get the template and convert it:
+        FileObject tplSnd = Templates.getTemplate(wizard);
+        FileObject tplShd = tplSnd.getParent().getChildren()[1];
+        
+        DataObject templateSnd = DataObject.find(tplSnd);
+        DataObject templateShd = DataObject.find(tplShd);
+
+        
+        
+        //Get the package:
+        FileObject dir = Templates.getTargetFolder(wizard);
+        DataFolder df = DataFolder.findFolder(dir);
+
+        ProjectAssetManager assetManager = new ProjectAssetManager(Templates.getProject(wizard),"assets");
+        
+        //Get the class:
+        String targetName = Templates.getTargetName(wizard);
+        String shaderName = targetName;
+        if (panel1.getDefType().equals("Fragment")) {
+            shaderName += ".frag";
+        } else if (panel1.getDefType().equals("Vertex")) {
+            shaderName += ".vert";
+        } else {
+            shaderName += ".frag";
+        }
+        
+        args.put("shaderSnippet",assetManager.getRelativeAssetPath(dir.getPath()+"/"+shaderName));
+
+        //Define the template from the above,
+        //passing the package, the file name, and the map of strings to the template:
+       // DataObject dobj = templateSnd.createFromTemplate(df, targetName, args);
+        
+       
+        DataObject sobj = templateShd.createFromTemplate(df, shaderName, args);
+ DataObject dobj = templateSnd.createFromTemplate(df, targetName, args);
+        //Obtain a FileObject:
+        createdFile = dobj.getPrimaryFile();
+
+        // Return the created file.
+        return Collections.singleton(createdFile);
+    }
+
+    @Override
+    public void initialize(WizardDescriptor wizard) {
+        this.wizard = wizard;
+    }
+
+    @Override
+    public void uninitialize(WizardDescriptor wizard) {
+        panels = null;
+    }
+
+    @Override
+    public WizardDescriptor.Panel<WizardDescriptor> current() {
+        return getPanels().get(index);
+    }
+
+    @Override
+    public String name() {
+        return index + 1 + ". from " + getPanels().size();
+    }
+
+    @Override
+    public boolean hasNext() {
+        return index < getPanels().size() - 1;
+    }
+
+    @Override
+    public boolean hasPrevious() {
+        return index > 0;
+    }
+
+    @Override
+    public void nextPanel() {
+        if (!hasNext()) {
+            throw new NoSuchElementException();
+        }
+        index++;
+    }
+
+    @Override
+    public void previousPanel() {
+        if (!hasPrevious()) {
+            throw new NoSuchElementException();
+        }
+        index--;
+    }
+
+    // If nothing unusual changes in the middle of the wizard, simply:
+    @Override
+    public void addChangeListener(ChangeListener l) {
+    }
+
+    @Override
+    public void removeChangeListener(ChangeListener l) {
+    }
+    // If something changes dynamically (besides moving between panels), e.g.
+    // the number of panels changes in response to user input, then use
+    // ChangeSupport to implement add/removeChangeListener and call fireChange
+    // when needed
+
+    // You could safely ignore this method. Is is here to keep steps which were
+    // there before this wizard was instantiated. It should be better handled
+    // by NetBeans Wizard API itself rather than needed to be implemented by a
+    // client code.
+    private String[] createSteps() {
+        String[] beforeSteps = (String[]) wizard.getProperty("WizardPanel_contentData");
+        assert beforeSteps != null : "This wizard may only be used embedded in the template wizard";
+        String[] res = new String[(beforeSteps.length - 1) + panels.size()];
+        for (int i = 0; i < res.length; i++) {
+            if (i < (beforeSteps.length - 1)) {
+                res[i] = beforeSteps[i];
+            } else {
+                res[i] = panels.get(i - beforeSteps.length + 1).getComponent().getName();
+            }
+        }
+        return res;
+    }
+
+}

+ 68 - 0
sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/wizard/SNDefWizardPanel1.java

@@ -0,0 +1,68 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.gde.shadernodedefinition.wizard;
+
+import javax.swing.event.ChangeListener;
+import org.openide.WizardDescriptor;
+import org.openide.util.HelpCtx;
+
+public class SNDefWizardPanel1 implements WizardDescriptor.Panel<WizardDescriptor> {
+
+    /**
+     * The visual component that displays this panel. If you need to access the
+     * component from this class, just use getComponent().
+     */
+    private SNDefVisualPanel1 component;
+
+    // Get the visual component for the panel. In this template, the component
+    // is kept separate. This can be more efficient: if the wizard is created
+    // but never displayed, or not all panels are displayed, it is better to
+    // create only those which really need to be visible.
+    @Override
+    public SNDefVisualPanel1 getComponent() {
+        if (component == null) {
+            component = new SNDefVisualPanel1();
+        }
+        return component;
+    }
+
+    @Override
+    public HelpCtx getHelp() {
+        // Show no Help button for this panel:
+        return HelpCtx.DEFAULT_HELP;
+        // If you have context help:
+        // return new HelpCtx("help.key.here");
+    }
+
+    @Override
+    public boolean isValid() {
+        // If it is always OK to press Next or Finish, then:
+        return true;
+        // If it depends on some condition (form filled out...) and
+        // this condition changes (last form field filled in...) then
+        // use ChangeSupport to implement add/removeChangeListener below.
+        // WizardDescriptor.ERROR/WARNING/INFORMATION_MESSAGE will also be useful.
+    }
+
+    @Override
+    public void addChangeListener(ChangeListener l) {
+    }
+
+    @Override
+    public void removeChangeListener(ChangeListener l) {
+    }
+
+    @Override
+    public void readSettings(WizardDescriptor wiz) {
+        // use wiz.getProperty to retrieve previous panel state
+    }
+
+    @Override
+    public void storeSettings(WizardDescriptor wiz) {
+        // use wiz.putProperty to remember current panel state
+    }
+
+}

+ 73 - 0
sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/wizard/SNDefWizardPanel2.java

@@ -0,0 +1,73 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.gde.shadernodedefinition.wizard;
+
+import javax.swing.event.ChangeListener;
+import org.openide.WizardDescriptor;
+import org.openide.util.HelpCtx;
+
+public class SNDefWizardPanel2 implements WizardDescriptor.Panel<WizardDescriptor> {
+
+    /**
+     * The visual component that displays this panel. If you need to access the
+     * component from this class, just use getComponent().
+     */
+    private SNDefVisualPanel2 component;
+    private final String type;
+
+    public SNDefWizardPanel2(String type) {
+        this.type = type;
+    }
+    
+    // Get the visual component for the panel. In this template, the component
+    // is kept separate. This can be more efficient: if the wizard is created
+    // but never displayed, or not all panels are displayed, it is better to
+    // create only those which really need to be visible.
+    @Override
+    public SNDefVisualPanel2 getComponent() {
+        if (component == null) {
+            component = new SNDefVisualPanel2(type);
+        }
+        return component;
+    }
+
+    @Override
+    public HelpCtx getHelp() {
+        // Show no Help button for this panel:
+        return HelpCtx.DEFAULT_HELP;
+        // If you have context help:
+        // return new HelpCtx("help.key.here");
+    }
+
+    @Override
+    public boolean isValid() {
+        // If it is always OK to press Next or Finish, then:
+        return true;
+        // If it depends on some condition (form filled out...) and
+        // this condition changes (last form field filled in...) then
+        // use ChangeSupport to implement add/removeChangeListener below.
+        // WizardDescriptor.ERROR/WARNING/INFORMATION_MESSAGE will also be useful.
+    }
+
+    @Override
+    public void addChangeListener(ChangeListener l) {
+    }
+
+    @Override
+    public void removeChangeListener(ChangeListener l) {
+    }
+
+    @Override
+    public void readSettings(WizardDescriptor wiz) {
+        // use wiz.getProperty to retrieve previous panel state
+    }
+
+    @Override
+    public void storeSettings(WizardDescriptor wiz) {
+        // use wiz.putProperty to remember current panel state
+    }
+
+}

+ 16 - 0
sdk/jme3-materialeditor/src/com/jme3/gde/shadernodedefinition/wizard/sNDef.html

@@ -0,0 +1,16 @@
+<!--
+To change this license header, choose License Headers in Project Properties.
+To change this template file, choose Tools | Templates
+and open the template in the editor.
+-->
+<html>
+    <head>
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+    <body>
+        <!--
+        TODO replace this with a description what your wizard is supposed to do.
+        This information will be displayed in the New Wizard Description area.
+        -->
+    </body>
+</html>