Browse Source

SDK :
- Added a material browser custom editor to pick materials.
- refactored the material preview to a widget, with possibility to preview on a sphere a box or a quad.
- changed the material editor preview by the new widget

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7960 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

rem..om 14 years ago
parent
commit
ae1f219a34

+ 3 - 0
jme3-materialeditor/src/com/jme3/gde/materials/Bundle.properties

@@ -7,3 +7,6 @@ Services/MIMEResolver/JMEMaterialDefinitionResolver.xml=MaterialDefinition Files
 Services/MIMEResolver/JMEMaterialResolver.xml=Material Files
 Templates/Other/JMEMaterialDefinitionTemplate.j3md=Empty MaterialDefinition file
 Templates/Other/JMEMaterialTemplate.j3m=Empty Material file
+MaterialBrowser.okButton.text=Ok
+MaterialBrowser.cancelButton.text=Cancel
+MaterialBrowser.title=Material Browser

+ 162 - 0
jme3-materialeditor/src/com/jme3/gde/materials/MaterialBrowser.form

@@ -0,0 +1,162 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.4" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
+  <Properties>
+    <Property name="defaultCloseOperation" type="int" value="2"/>
+    <Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+      <ResourceString bundle="com/jme3/gde/materials/Bundle.properties" key="MaterialBrowser.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+    </Property>
+  </Properties>
+  <SyntheticProperties>
+    <SyntheticProperty name="formSizePolicy" type="int" value="2"/>
+  </SyntheticProperties>
+  <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="false"/>
+    <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">
+          <Group type="102" alignment="0" attributes="0">
+              <Component id="jScrollPane1" min="-2" pref="257" max="-2" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Component id="jScrollPane2" pref="483" max="32767" attributes="0"/>
+                  <Component id="jPanel1" max="32767" attributes="0"/>
+                  <Group type="102" alignment="0" attributes="0">
+                      <Component id="jPanel2" max="32767" attributes="0"/>
+                      <EmptySpace max="-2" attributes="0"/>
+                  </Group>
+              </Group>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <Component id="jPanel1" min="-2" max="-2" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="jScrollPane2" pref="250" max="32767" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="jPanel2" min="-2" max="-2" attributes="1"/>
+          </Group>
+          <Component id="jScrollPane1" alignment="0" pref="497" 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.JTree" name="jTree1">
+        </Component>
+      </SubComponents>
+    </Container>
+    <Container class="javax.swing.JPanel" name="jPanel1">
+      <Properties>
+        <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+          <Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo">
+            <LineBorder>
+              <Color PropertyName="color" blue="99" green="99" red="99" type="rgb"/>
+            </LineBorder>
+          </Border>
+        </Property>
+      </Properties>
+
+      <Layout>
+        <DimensionLayout dim="0">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Component id="materialPreviewWidget1" alignment="0" pref="481" max="32767" attributes="0"/>
+          </Group>
+        </DimensionLayout>
+        <DimensionLayout dim="1">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Component id="materialPreviewWidget1" min="-2" pref="188" max="-2" attributes="0"/>
+          </Group>
+        </DimensionLayout>
+      </Layout>
+      <SubComponents>
+        <Component class="com.jme3.gde.materials.multiview.widgets.MaterialPreviewWidget" name="materialPreviewWidget1">
+        </Component>
+      </SubComponents>
+    </Container>
+    <Container class="javax.swing.JScrollPane" name="jScrollPane2">
+      <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="materialTextPreview">
+          <Properties>
+            <Property name="columns" type="int" value="20"/>
+            <Property name="editable" type="boolean" value="false"/>
+            <Property name="rows" type="int" value="5"/>
+          </Properties>
+        </Component>
+      </SubComponents>
+    </Container>
+    <Container class="javax.swing.JPanel" name="jPanel2">
+
+      <Layout>
+        <DimensionLayout dim="0">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" alignment="1" attributes="0">
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Component id="cancelButton" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace pref="343" max="32767" attributes="0"/>
+                  <Component id="okButton" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace max="-2" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+        <DimensionLayout dim="1">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" attributes="0">
+                  <EmptySpace max="32767" attributes="0"/>
+                  <Group type="103" groupAlignment="3" attributes="0">
+                      <Component id="okButton" alignment="3" min="-2" max="-2" attributes="0"/>
+                      <Component id="cancelButton" alignment="3" min="-2" max="-2" attributes="1"/>
+                  </Group>
+                  <EmptySpace max="-2" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+      </Layout>
+      <SubComponents>
+        <Component class="javax.swing.JButton" name="okButton">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/materials/Bundle.properties" key="MaterialBrowser.okButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="okButtonActionPerformed"/>
+          </Events>
+        </Component>
+        <Component class="javax.swing.JButton" name="cancelButton">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/materials/Bundle.properties" key="MaterialBrowser.cancelButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonActionPerformed"/>
+          </Events>
+        </Component>
+      </SubComponents>
+    </Container>
+  </SubComponents>
+</Form>

+ 263 - 0
jme3-materialeditor/src/com/jme3/gde/materials/MaterialBrowser.java

@@ -0,0 +1,263 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/*
+ * MaterialBrowser.java
+ *
+ * Created on 31 juil. 2011, 12:20:52
+ */
+package com.jme3.gde.materials;
+
+import com.jme3.gde.core.assets.ProjectAssetManager;
+import com.jme3.gde.core.util.TreeUtil;
+import com.jme3.material.Material;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.logging.Logger;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.TreeNode;
+import javax.swing.tree.TreePath;
+import javax.swing.tree.TreeSelectionModel;
+import org.openide.util.Exceptions;
+
+/**
+ * @author Nehon
+ */
+public class MaterialBrowser extends javax.swing.JDialog implements TreeSelectionListener, WindowListener {
+
+    private ProjectAssetManager assetManager;
+    private MaterialPropertyEditor editor;
+
+    /** Creates new form MaterialBrowser */
+    public MaterialBrowser(java.awt.Frame parent, boolean modal, ProjectAssetManager assetManager, MaterialPropertyEditor editor) {
+        this.assetManager = assetManager;
+        this.editor = editor;
+        initComponents();
+        loadAvailableMaterials();
+        setSelectedMaterial((Material) editor.getValue());
+        setLocationRelativeTo(null);
+    }
+
+    private void loadAvailableMaterials() {
+        if (assetManager == null) {
+            return;
+        }
+        String[] leaves = assetManager.getMaterials();
+        TreeUtil.createTree(jTree1, leaves);
+        TreeUtil.expandTree(jTree1, (TreeNode) jTree1.getModel().getRoot(), 1);
+        jTree1.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
+        jTree1.addTreeSelectionListener(this);
+    }
+
+    private void setMaterial() {
+        DefaultMutableTreeNode node = (DefaultMutableTreeNode) jTree1.getLastSelectedPathComponent();
+
+        if (node != null && node.isLeaf()) {
+            String selected = TreeUtil.getPath(node.getUserObjectPath());
+            selected = selected.substring(0, selected.lastIndexOf("/"));
+            Material mat = assetManager.loadMaterial(selected);
+            editor.setValue(mat);
+            editor.setAsText(selected);
+        } else {
+            editor.setValue(null);
+            editor.setAsText(null);
+        }
+
+    }
+
+    private void setSelectedMaterial(Material material) {
+        if (material != null) {
+            Logger.getLogger(MaterialBrowser.class.getName()).finer("Looking for Texture: " + material.getAssetName());
+            String[] path = ("/" + material.getAssetName()).split("/");
+            TreePath parent = new TreePath((TreeNode) jTree1.getModel().getRoot());
+            jTree1.expandPath(TreeUtil.buildTreePath(jTree1, parent, path, 0, true));
+            jTree1.getSelectionModel().setSelectionPath(TreeUtil.buildTreePath(jTree1, parent, path, 0, false));
+
+        }
+    }
+
+    public void valueChanged(TreeSelectionEvent e) {
+        DefaultMutableTreeNode node = (DefaultMutableTreeNode) jTree1.getLastSelectedPathComponent();
+
+        if (node == null) {
+            return;
+        }
+
+        if (node.isLeaf()) {
+            String selected = TreeUtil.getPath(node.getUserObjectPath());
+            selected = selected.substring(0, selected.lastIndexOf("/"));
+
+            materialPreviewWidget1.showMaterial(assetManager, selected);
+
+            try {
+                FileReader fr = new FileReader(assetManager.getAbsoluteAssetPath(selected));
+
+                if (fr != null) {
+                    char[] b = new char[5000];//preview 5000 char
+                    fr.read(b);
+                    materialTextPreview.setText(new String(b).trim());
+                }
+            } catch (IOException ex) {
+                Exceptions.printStackTrace(ex);
+            }
+
+        } else {
+            materialPreviewWidget1.clear();
+            materialTextPreview.setText("");
+        }
+
+    }
+
+    /** 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.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        jScrollPane1 = new javax.swing.JScrollPane();
+        jTree1 = new javax.swing.JTree();
+        jPanel1 = new javax.swing.JPanel();
+        materialPreviewWidget1 = new com.jme3.gde.materials.multiview.widgets.MaterialPreviewWidget();
+        jScrollPane2 = new javax.swing.JScrollPane();
+        materialTextPreview = new javax.swing.JTextArea();
+        jPanel2 = new javax.swing.JPanel();
+        okButton = new javax.swing.JButton();
+        cancelButton = new javax.swing.JButton();
+
+        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+        setTitle(org.openide.util.NbBundle.getMessage(MaterialBrowser.class, "MaterialBrowser.title")); // NOI18N
+
+        jScrollPane1.setViewportView(jTree1);
+
+        jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(153, 153, 153)));
+
+        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
+        jPanel1.setLayout(jPanel1Layout);
+        jPanel1Layout.setHorizontalGroup(
+            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(materialPreviewWidget1, javax.swing.GroupLayout.DEFAULT_SIZE, 481, Short.MAX_VALUE)
+        );
+        jPanel1Layout.setVerticalGroup(
+            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(materialPreviewWidget1, javax.swing.GroupLayout.PREFERRED_SIZE, 188, javax.swing.GroupLayout.PREFERRED_SIZE)
+        );
+
+        materialTextPreview.setColumns(20);
+        materialTextPreview.setEditable(false);
+        materialTextPreview.setRows(5);
+        jScrollPane2.setViewportView(materialTextPreview);
+
+        okButton.setText(org.openide.util.NbBundle.getMessage(MaterialBrowser.class, "MaterialBrowser.okButton.text")); // NOI18N
+        okButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                okButtonActionPerformed(evt);
+            }
+        });
+
+        cancelButton.setText(org.openide.util.NbBundle.getMessage(MaterialBrowser.class, "MaterialBrowser.cancelButton.text")); // NOI18N
+        cancelButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                cancelButtonActionPerformed(evt);
+            }
+        });
+
+        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
+        jPanel2.setLayout(jPanel2Layout);
+        jPanel2Layout.setHorizontalGroup(
+            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
+                .addContainerGap()
+                .addComponent(cancelButton)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 343, Short.MAX_VALUE)
+                .addComponent(okButton)
+                .addContainerGap())
+        );
+        jPanel2Layout.setVerticalGroup(
+            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(jPanel2Layout.createSequentialGroup()
+                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(okButton)
+                    .addComponent(cancelButton))
+                .addContainerGap())
+        );
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+        getContentPane().setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 257, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 483, Short.MAX_VALUE)
+                    .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                    .addGroup(layout.createSequentialGroup()
+                        .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                        .addContainerGap())))
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 250, Short.MAX_VALUE)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 497, Short.MAX_VALUE)
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
+    setMaterial();
+    dispose();
+    materialPreviewWidget1.cleanUp();
+}//GEN-LAST:event_okButtonActionPerformed
+
+private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
+    dispose();
+    materialPreviewWidget1.cleanUp();
+}//GEN-LAST:event_cancelButtonActionPerformed
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JButton cancelButton;
+    private javax.swing.JPanel jPanel1;
+    private javax.swing.JPanel jPanel2;
+    private javax.swing.JScrollPane jScrollPane1;
+    private javax.swing.JScrollPane jScrollPane2;
+    private javax.swing.JTree jTree1;
+    private com.jme3.gde.materials.multiview.widgets.MaterialPreviewWidget materialPreviewWidget1;
+    private javax.swing.JTextArea materialTextPreview;
+    private javax.swing.JButton okButton;
+    // End of variables declaration//GEN-END:variables
+
+    public void windowOpened(WindowEvent e) {
+    }
+
+    public void windowClosing(WindowEvent e) {
+        materialPreviewWidget1.cleanUp();
+    }
+
+    public void windowClosed(WindowEvent e) {
+    }
+
+    public void windowIconified(WindowEvent e) {
+    }
+
+    public void windowDeiconified(WindowEvent e) {
+    }
+
+    public void windowActivated(WindowEvent e) {
+    }
+
+    public void windowDeactivated(WindowEvent e) {
+    }
+}

+ 12 - 4
jme3-materialeditor/src/com/jme3/gde/materials/MaterialPropertyEditor.java

@@ -125,7 +125,7 @@ public class MaterialPropertyEditor implements PropertyEditor, SceneExplorerProp
                 Exceptions.printStackTrace(ex);
                 return;
             }
-        }else{
+        } else {
             applyMaterial(text);
         }
     }
@@ -138,7 +138,7 @@ public class MaterialPropertyEditor implements PropertyEditor, SceneExplorerProp
                 public Void call() throws Exception {
                     SceneRequest request = SceneApplication.getApplication().getCurrentSceneRequest();
                     ((DesktopAssetManager) request.getManager()).deleteFromCache(new MaterialKey(text));
-                    Material localMaterial = (Material) request.getManager().loadMaterial(text);
+                    Material localMaterial = request.getManager().loadMaterial(text);
                     if (localMaterial != null) {
                         material = localMaterial;
                     }
@@ -173,11 +173,19 @@ public class MaterialPropertyEditor implements PropertyEditor, SceneExplorerProp
     }
 
     public Component getCustomEditor() {
-        throw new UnsupportedOperationException("Not supported yet.");
+        ProjectAssetManager currentProjectAssetManager = null;
+
+        if (currentProjectAssetManager == null) {
+            currentProjectAssetManager = (ProjectAssetManager) SceneApplication.getApplication().getAssetManager();
+        }
+        MaterialBrowser materialBrowser = new MaterialBrowser(null, true, currentProjectAssetManager, this);
+        return materialBrowser;
+
+
     }
 
     public boolean supportsCustomEditor() {
-        return false;
+        return true;
     }
 
     public void addPropertyChangeListener(PropertyChangeListener listener) {

+ 0 - 2
jme3-materialeditor/src/com/jme3/gde/materials/multiview/Bundle.properties

@@ -2,13 +2,11 @@ CTL_MaterialEditorAction=MaterialEditor
 CTL_MaterialEditorTopComponent=MaterialEditor Window
 HINT_MaterialEditorTopComponent=This is a MaterialEditor window
 MaterialEditorTopComponent.jLabel1.text=Material Definition
-MaterialEditorTopComponent.jLabel2.text=
 MaterialEditorTopComponent.jScrollPane1.TabConstraints.tabTitle=Source
 MaterialEditorTopComponent.jScrollPane2.TabConstraints.tabTitle=Properties
 MaterialEditorTopComponent.jPanel4.TabConstraints.tabTitle=Editor
 MaterialEditorTopComponent.jLabel3.text=Name
 MaterialEditorTopComponent.jTextField1.text=jTextField1
-MaterialEditorTopComponent.jToolBar1.toolTipText=preview - updates when saved
 MaterialEditorTopComponent.jScrollPane3.TabConstraints.tabTitle=Textures & Colors
 MaterialEditorTopComponent.jScrollPane9.TabConstraints.tabTitle=Additional RenderState
 MaterialEditorTopComponent.jScrollPane2.TabConstraints.tabTitle_1=Options

+ 25 - 50
jme3-materialeditor/src/com/jme3/gde/materials/multiview/MaterialEditorTopComponent.form

@@ -38,12 +38,12 @@
   <Layout>
     <DimensionLayout dim="0">
       <Group type="103" groupAlignment="0" attributes="0">
-          <Component id="jTabbedPane1" alignment="0" pref="593" max="32767" attributes="0"/>
+          <Component id="jTabbedPane1" alignment="0" pref="769" max="32767" attributes="0"/>
       </Group>
     </DimensionLayout>
     <DimensionLayout dim="1">
       <Group type="103" groupAlignment="0" attributes="0">
-          <Component id="jTabbedPane1" alignment="1" pref="466" max="32767" attributes="0"/>
+          <Component id="jTabbedPane1" alignment="1" pref="524" max="32767" attributes="0"/>
       </Group>
     </DimensionLayout>
   </Layout>
@@ -85,19 +85,22 @@
           <Layout>
             <DimensionLayout dim="0">
               <Group type="103" groupAlignment="0" attributes="0">
-                  <Group type="102" alignment="0" attributes="0">
-                      <Component id="jToolBar1" min="-2" pref="120" max="-2" attributes="0"/>
-                      <EmptySpace max="-2" attributes="0"/>
+                  <Group type="102" alignment="1" attributes="0">
+                      <Component id="materialPreviewWidget1" min="-2" pref="120" max="-2" attributes="0"/>
+                      <EmptySpace min="-2" pref="32" max="-2" attributes="0"/>
                       <Group type="103" groupAlignment="0" attributes="0">
-                          <Component id="jCheckBox1" alignment="1" min="-2" max="-2" attributes="0"/>
-                          <Component id="jToolBar3" alignment="0" pref="452" max="32767" attributes="1"/>
-                          <Component id="jToolBar2" alignment="0" pref="452" max="32767" attributes="0"/>
+                          <Group type="102" alignment="0" attributes="0">
+                              <EmptySpace min="-2" pref="438" max="-2" attributes="0"/>
+                              <Component id="jCheckBox1" min="-2" max="-2" attributes="0"/>
+                          </Group>
+                          <Component id="jToolBar3" alignment="0" pref="612" max="32767" attributes="1"/>
+                          <Component id="jToolBar2" alignment="0" pref="612" max="32767" attributes="1"/>
                       </Group>
                   </Group>
                   <Group type="102" attributes="0">
                       <Component id="jTabbedPane3" min="-2" pref="223" max="-2" attributes="0"/>
                       <EmptySpace max="-2" attributes="0"/>
-                      <Component id="jTabbedPane2" pref="349" max="32767" attributes="0"/>
+                      <Component id="jTabbedPane2" pref="535" max="32767" attributes="0"/>
                   </Group>
               </Group>
             </DimensionLayout>
@@ -105,56 +108,26 @@
               <Group type="103" groupAlignment="0" attributes="0">
                   <Group type="102" alignment="0" attributes="0">
                       <Group type="103" groupAlignment="0" attributes="0">
-                          <Group type="102" alignment="1" attributes="1">
+                          <Group type="102" attributes="0">
                               <EmptySpace max="-2" attributes="0"/>
                               <Component id="jToolBar3" min="-2" pref="25" max="-2" attributes="0"/>
-                              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                              <EmptySpace max="-2" attributes="0"/>
                               <Component id="jToolBar2" min="-2" pref="25" max="-2" attributes="0"/>
-                              <EmptySpace type="separate" max="-2" attributes="0"/>
+                              <EmptySpace min="-2" pref="23" max="-2" attributes="0"/>
                               <Component id="jCheckBox1" min="-2" max="-2" attributes="0"/>
-                              <EmptySpace min="-2" pref="3" max="-2" attributes="0"/>
                           </Group>
-                          <Component id="jToolBar1" min="-2" pref="120" max="-2" attributes="0"/>
+                          <Component id="materialPreviewWidget1" min="-2" pref="152" max="-2" attributes="0"/>
                       </Group>
-                      <EmptySpace min="-2" pref="3" max="-2" attributes="0"/>
-                      <Group type="103" groupAlignment="0" attributes="0">
-                          <Component id="jTabbedPane3" pref="297" max="32767" attributes="0"/>
-                          <Component id="jTabbedPane2" alignment="0" pref="297" max="32767" attributes="0"/>
+                      <EmptySpace max="-2" attributes="0"/>
+                      <Group type="103" groupAlignment="1" attributes="0">
+                          <Component id="jTabbedPane2" pref="338" max="32767" attributes="0"/>
+                          <Component id="jTabbedPane3" pref="338" max="32767" attributes="0"/>
                       </Group>
                   </Group>
               </Group>
             </DimensionLayout>
           </Layout>
           <SubComponents>
-            <Container class="javax.swing.JToolBar" name="jToolBar1">
-              <Properties>
-                <Property name="floatable" type="boolean" value="false"/>
-                <Property name="rollover" type="boolean" value="true"/>
-                <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
-                  <ResourceString bundle="com/jme3/gde/materials/multiview/Bundle.properties" key="MaterialEditorTopComponent.jToolBar1.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
-                </Property>
-                <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
-                  <Dimension value="[120, 120]"/>
-                </Property>
-              </Properties>
-
-              <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
-              <SubComponents>
-                <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/materials/multiview/Bundle.properties" key="MaterialEditorTopComponent.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
-                    </Property>
-                    <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
-                      <Dimension value="[120, 120]"/>
-                    </Property>
-                  </Properties>
-                  <Events>
-                    <EventHandler event="mouseReleased" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="reloadPreview"/>
-                  </Events>
-                </Component>
-              </SubComponents>
-            </Container>
             <Container class="javax.swing.JTabbedPane" name="jTabbedPane2">
 
               <Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/>
@@ -303,12 +276,12 @@
                   <Layout>
                     <DimensionLayout dim="0">
                       <Group type="103" groupAlignment="0" attributes="0">
-                          <EmptySpace min="0" pref="0" max="32767" attributes="0"/>
+                          <EmptySpace min="0" pref="276" max="32767" attributes="0"/>
                       </Group>
                     </DimensionLayout>
                     <DimensionLayout dim="1">
                       <Group type="103" groupAlignment="0" attributes="0">
-                          <EmptySpace min="0" pref="21" max="32767" attributes="0"/>
+                          <EmptySpace min="0" pref="23" max="32767" attributes="0"/>
                       </Group>
                     </DimensionLayout>
                   </Layout>
@@ -380,7 +353,7 @@
                     </DimensionLayout>
                     <DimensionLayout dim="1">
                       <Group type="103" groupAlignment="0" attributes="0">
-                          <EmptySpace min="0" pref="21" max="32767" attributes="0"/>
+                          <EmptySpace min="0" pref="23" max="32767" attributes="0"/>
                       </Group>
                     </DimensionLayout>
                   </Layout>
@@ -408,6 +381,8 @@
                 <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jCheckBox1ActionPerformed"/>
               </Events>
             </Component>
+            <Component class="com.jme3.gde.materials.multiview.widgets.MaterialPreviewWidget" name="materialPreviewWidget1">
+            </Component>
           </SubComponents>
         </Container>
         <Container class="javax.swing.JScrollPane" name="jScrollPane1">

+ 29 - 99
jme3-materialeditor/src/com/jme3/gde/materials/multiview/MaterialEditorTopComponent.java

@@ -4,22 +4,13 @@
  */
 package com.jme3.gde.materials.multiview;
 
-import com.jme3.asset.MaterialKey;
 import com.jme3.gde.core.assets.AssetDataObject;
 import com.jme3.gde.core.assets.ProjectAssetManager;
-import com.jme3.gde.core.scene.PreviewRequest;
-import com.jme3.gde.core.scene.SceneApplication;
-import com.jme3.gde.core.scene.SceneListener;
-import com.jme3.gde.core.scene.SceneRequest;
 import com.jme3.gde.materials.EditableMaterialFile;
 import com.jme3.gde.materials.MaterialProperty;
 import com.jme3.gde.materials.multiview.widgets.MaterialPropertyWidget;
 import com.jme3.gde.materials.multiview.widgets.MaterialWidgetListener;
 import com.jme3.gde.materials.multiview.widgets.WidgetFactory;
-import com.jme3.material.Material;
-import com.jme3.scene.Geometry;
-import com.jme3.scene.shape.Sphere;
-import com.jme3.util.TangentBinormalGenerator;
 import java.awt.Component;
 import java.io.File;
 import java.io.IOException;
@@ -28,7 +19,6 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Map.Entry;
 import java.util.logging.Logger;
-import javax.swing.ImageIcon;
 import javax.swing.event.DocumentEvent;
 import javax.swing.event.DocumentListener;
 import org.openide.loaders.DataObjectNotFoundException;
@@ -52,7 +42,7 @@ import org.openide.windows.CloneableTopComponent;
  */
 @ConvertAsProperties(dtd = "-//com.jme3.gde.materials.multiview//MaterialEditor//EN",
 autostore = false)
-public final class MaterialEditorTopComponent extends CloneableTopComponent implements SceneListener, MaterialWidgetListener {
+public final class MaterialEditorTopComponent extends CloneableTopComponent implements MaterialWidgetListener {
 
     private static MaterialEditorTopComponent instance;
     /** path to the icon used by the component and its open action */
@@ -65,7 +55,6 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
     private EditableMaterialFile materialFile;
     private String materialFileName;
     private ProjectAssetManager manager;
-    private Sphere sphMesh;
     private SaveCookie saveCookie = new SaveCookieImpl();
     private boolean saveImmediate = true;
     private boolean updateProperties = false;
@@ -96,14 +85,8 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
         }
         jTextArea1.getDocument().addDocumentListener(new DocumentChangeListener());
 
-        SceneApplication.getApplication().addSceneListener(this);
-
-        sphMesh = new Sphere(32, 32, 2.5f);
-        sphMesh.setTextureMode(Sphere.TextureMode.Projected);
-        sphMesh.updateGeometry(32, 32, 2.5f, false, false);
-        TangentBinormalGenerator.generate(sphMesh);
         updateProperties();
-        showMaterial();
+        materialPreviewWidget1.showMaterial(manager, materialFileName);
     }
 
     /** This method is called from within the constructor to
@@ -117,8 +100,6 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
         jPanel2 = new javax.swing.JPanel();
         jTabbedPane1 = new javax.swing.JTabbedPane();
         jPanel4 = new javax.swing.JPanel();
-        jToolBar1 = new javax.swing.JToolBar();
-        jLabel2 = new javax.swing.JLabel();
         jTabbedPane2 = new javax.swing.JTabbedPane();
         jScrollPane3 = new javax.swing.JScrollPane();
         texturePanel = new javax.swing.JPanel();
@@ -136,6 +117,7 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
         jPanel1 = new javax.swing.JPanel();
         jTextField1 = new javax.swing.JTextField();
         jCheckBox1 = new javax.swing.JCheckBox();
+        materialPreviewWidget1 = new com.jme3.gde.materials.multiview.widgets.MaterialPreviewWidget();
         jScrollPane1 = new javax.swing.JScrollPane();
         jTextArea1 = new javax.swing.JTextArea();
 
@@ -159,20 +141,6 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
         jPanel4.setBackground(new java.awt.Color(204, 204, 204));
         jPanel4.setPreferredSize(new java.awt.Dimension(0, 0));
 
-        jToolBar1.setFloatable(false);
-        jToolBar1.setRollover(true);
-        jToolBar1.setToolTipText(org.openide.util.NbBundle.getMessage(MaterialEditorTopComponent.class, "MaterialEditorTopComponent.jToolBar1.toolTipText")); // NOI18N
-        jToolBar1.setPreferredSize(new java.awt.Dimension(120, 120));
-
-        org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(MaterialEditorTopComponent.class, "MaterialEditorTopComponent.jLabel2.text")); // NOI18N
-        jLabel2.setPreferredSize(new java.awt.Dimension(120, 120));
-        jLabel2.addMouseListener(new java.awt.event.MouseAdapter() {
-            public void mouseReleased(java.awt.event.MouseEvent evt) {
-                reloadPreview(evt);
-            }
-        });
-        jToolBar1.add(jLabel2);
-
         jScrollPane3.setBackground(new java.awt.Color(204, 204, 204));
         jScrollPane3.setBorder(null);
         jScrollPane3.setMinimumSize(new java.awt.Dimension(0, 0));
@@ -215,11 +183,11 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
         jPanel3.setLayout(jPanel3Layout);
         jPanel3Layout.setHorizontalGroup(
             jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGap(0, 0, Short.MAX_VALUE)
+            .addGap(0, 276, Short.MAX_VALUE)
         );
         jPanel3Layout.setVerticalGroup(
             jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGap(0, 21, Short.MAX_VALUE)
+            .addGap(0, 23, Short.MAX_VALUE)
         );
 
         jToolBar2.add(jPanel3);
@@ -251,7 +219,7 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
         );
         jPanel1Layout.setVerticalGroup(
             jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGap(0, 21, Short.MAX_VALUE)
+            .addGap(0, 23, Short.MAX_VALUE)
         );
 
         jToolBar3.add(jPanel1);
@@ -276,35 +244,36 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
         jPanel4.setLayout(jPanel4Layout);
         jPanel4Layout.setHorizontalGroup(
             jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGroup(jPanel4Layout.createSequentialGroup()
-                .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)
-                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel4Layout.createSequentialGroup()
+                .addComponent(materialPreviewWidget1, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addGap(32, 32, 32)
                 .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-                    .addComponent(jCheckBox1, javax.swing.GroupLayout.Alignment.TRAILING)
-                    .addComponent(jToolBar3, javax.swing.GroupLayout.DEFAULT_SIZE, 452, Short.MAX_VALUE)
-                    .addComponent(jToolBar2, javax.swing.GroupLayout.DEFAULT_SIZE, 452, Short.MAX_VALUE)))
+                    .addGroup(jPanel4Layout.createSequentialGroup()
+                        .addGap(438, 438, 438)
+                        .addComponent(jCheckBox1))
+                    .addComponent(jToolBar3, javax.swing.GroupLayout.DEFAULT_SIZE, 612, Short.MAX_VALUE)
+                    .addComponent(jToolBar2, javax.swing.GroupLayout.DEFAULT_SIZE, 612, Short.MAX_VALUE)))
             .addGroup(jPanel4Layout.createSequentialGroup()
                 .addComponent(jTabbedPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 223, javax.swing.GroupLayout.PREFERRED_SIZE)
                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addComponent(jTabbedPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 349, Short.MAX_VALUE))
+                .addComponent(jTabbedPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 535, Short.MAX_VALUE))
         );
         jPanel4Layout.setVerticalGroup(
             jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
             .addGroup(jPanel4Layout.createSequentialGroup()
                 .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel4Layout.createSequentialGroup()
+                    .addGroup(jPanel4Layout.createSequentialGroup()
                         .addContainerGap()
                         .addComponent(jToolBar3, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
-                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                         .addComponent(jToolBar2, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
-                        .addGap(18, 18, 18)
-                        .addComponent(jCheckBox1)
-                        .addGap(3, 3, 3))
-                    .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE))
-                .addGap(3, 3, 3)
-                .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-                    .addComponent(jTabbedPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 297, Short.MAX_VALUE)
-                    .addComponent(jTabbedPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 297, Short.MAX_VALUE)))
+                        .addGap(23, 23, 23)
+                        .addComponent(jCheckBox1))
+                    .addComponent(materialPreviewWidget1, javax.swing.GroupLayout.PREFERRED_SIZE, 152, javax.swing.GroupLayout.PREFERRED_SIZE))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+                    .addComponent(jTabbedPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 338, Short.MAX_VALUE)
+                    .addComponent(jTabbedPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 338, Short.MAX_VALUE)))
         );
 
         jTabbedPane1.addTab(org.openide.util.NbBundle.getMessage(MaterialEditorTopComponent.class, "MaterialEditorTopComponent.jPanel4.TabConstraints.tabTitle"), jPanel4); // NOI18N
@@ -319,11 +288,11 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
         this.setLayout(layout);
         layout.setHorizontalGroup(
             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 593, Short.MAX_VALUE)
+            .addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 769, Short.MAX_VALUE)
         );
         layout.setVerticalGroup(
             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addComponent(jTabbedPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 466, Short.MAX_VALUE)
+            .addComponent(jTabbedPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 524, Short.MAX_VALUE)
         );
     }// </editor-fold>//GEN-END:initComponents
 
@@ -336,10 +305,6 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
         }
     }//GEN-LAST:event_jComboBox1ActionPerformed
 
-    private void reloadPreview(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_reloadPreview
-        showMaterial();
-    }//GEN-LAST:event_reloadPreview
-
     private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextField1ActionPerformed
         if (materialFile != null) {
             materialFile.setName(jTextField1.getText());
@@ -355,7 +320,6 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
     private javax.swing.JCheckBox jCheckBox1;
     private javax.swing.JComboBox jComboBox1;
     private javax.swing.JLabel jLabel1;
-    private javax.swing.JLabel jLabel2;
     private javax.swing.JLabel jLabel3;
     private javax.swing.JPanel jPanel1;
     private javax.swing.JPanel jPanel2;
@@ -370,9 +334,9 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
     private javax.swing.JTabbedPane jTabbedPane3;
     private javax.swing.JTextArea jTextArea1;
     private javax.swing.JTextField jTextField1;
-    private javax.swing.JToolBar jToolBar1;
     private javax.swing.JToolBar jToolBar2;
     private javax.swing.JToolBar jToolBar3;
+    private com.jme3.gde.materials.multiview.widgets.MaterialPreviewWidget materialPreviewWidget1;
     private javax.swing.JPanel optionsPanel;
     private javax.swing.JPanel statesPanel;
     private javax.swing.JPanel texturePanel;
@@ -429,7 +393,7 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
 
     @Override
     public void componentClosed() {
-        SceneApplication.getApplication().removeSceneListener(this);
+        materialPreviewWidget1.cleanUp();
     }
 
     void writeProperties(java.util.Properties p) {
@@ -507,7 +471,7 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
             String text = jTextArea1.getText();
             materialFile.setAsText(text);
             dataObject.setModified(false);
-            showMaterial();
+            materialPreviewWidget1.showMaterial(manager, materialFileName);
         }
     }
 
@@ -617,40 +581,6 @@ public final class MaterialEditorTopComponent extends CloneableTopComponent impl
         }
     }
 
-    @SuppressWarnings("unchecked")
-    private void showMaterial() {
-        try {
-            MaterialKey key = new MaterialKey(manager.getRelativeAssetPath(materialFileName));
-            Geometry geom = new Geometry("TestSphere", sphMesh);
-            manager.deleteFromCache(key);
-            geom.setMaterial((Material) manager.loadAsset(key));
-            if (geom.getMaterial() != null) {
-                PreviewRequest request = new PreviewRequest(this, geom);
-                SceneApplication.getApplication().createPreview(request);
-            }
-        } catch (Exception e) {
-        }
-    }
-
-    public void sceneRequested(SceneRequest request) {
-    }
-
-    public boolean sceneClose(SceneRequest request) {
-        return true;
-    }
-
-    public void previewRequested(PreviewRequest request) {
-        if (request.getRequester() == this) {
-            final ImageIcon icon = new ImageIcon(request.getImage());
-            java.awt.EventQueue.invokeLater(new Runnable() {
-
-                public void run() {
-                    jLabel2.setIcon(icon);
-                }
-            });
-        }
-    }
-
     public void propertyChanged(MaterialProperty property) {
         String string = materialFile.getUpdatedContent();
         jTextArea1.setText(string);

+ 7 - 0
jme3-materialeditor/src/com/jme3/gde/materials/multiview/widgets/Bundle.properties

@@ -31,3 +31,10 @@ TexturePanel.jCheckBox1.text=flip
 OnOffPanel.jLabel1.text=jLabel1
 OnOffPanel.jCheckBox1.text=
 TexturePanel.jCheckBox2.text=repeat
+MaterialPreviewWidget.sphereButton.text=
+MaterialPreviewWidget.cubeButton.text=
+MaterialPreviewWidget.planeButton.text=
+MaterialPreviewWidget.sphereButton.toolTipText=Preview material on a sphere
+MaterialPreviewWidget.cubeButton.toolTipText=Preview material on a cube
+MaterialPreviewWidget.planeButton.toolTipText=Preview material on a plane
+MaterialPreviewWidget.previewLabel.text=

+ 126 - 0
jme3-materialeditor/src/com/jme3/gde/materials/multiview/widgets/MaterialPreviewWidget.form

@@ -0,0 +1,126 @@
+<?xml version="1.1" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <NonVisualComponents>
+    <Component class="javax.swing.ButtonGroup" name="toggleButtonGroup">
+    </Component>
+  </NonVisualComponents>
+  <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="false"/>
+    <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="previewLabel" alignment="0" pref="120" max="32767" attributes="0"/>
+          <Component id="jToolBar1" alignment="0" pref="120" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="1" attributes="0">
+              <Component id="previewLabel" pref="120" max="32767" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="jToolBar1" min="-2" pref="25" max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Component class="javax.swing.JLabel" name="previewLabel">
+      <Properties>
+        <Property name="horizontalAlignment" type="int" value="0"/>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="com/jme3/gde/materials/multiview/widgets/Bundle.properties" key="MaterialPreviewWidget.previewLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Container class="javax.swing.JToolBar" name="jToolBar1">
+      <Properties>
+        <Property name="floatable" type="boolean" value="false"/>
+        <Property name="rollover" type="boolean" value="true"/>
+      </Properties>
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
+      <SubComponents>
+        <Component class="javax.swing.JToggleButton" name="sphereButton">
+          <Properties>
+            <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
+              <ComponentRef name="toggleButtonGroup"/>
+            </Property>
+            <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/sphere.png"/>
+            </Property>
+            <Property name="selected" type="boolean" value="true"/>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/materials/multiview/widgets/Bundle.properties" key="MaterialPreviewWidget.sphereButton.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/materials/multiview/widgets/Bundle.properties" key="MaterialPreviewWidget.sphereButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="focusable" type="boolean" value="false"/>
+            <Property name="horizontalAlignment" type="int" value="4"/>
+            <Property name="horizontalTextPosition" type="int" value="0"/>
+            <Property name="verticalTextPosition" type="int" value="3"/>
+          </Properties>
+          <Events>
+            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="sphereButtonActionPerformed"/>
+          </Events>
+        </Component>
+        <Component class="javax.swing.JToggleButton" name="cubeButton">
+          <Properties>
+            <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
+              <ComponentRef name="toggleButtonGroup"/>
+            </Property>
+            <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/box.png"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/materials/multiview/widgets/Bundle.properties" key="MaterialPreviewWidget.cubeButton.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/materials/multiview/widgets/Bundle.properties" key="MaterialPreviewWidget.cubeButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="focusable" type="boolean" value="false"/>
+            <Property name="horizontalTextPosition" type="int" value="0"/>
+            <Property name="verticalTextPosition" type="int" value="3"/>
+          </Properties>
+          <Events>
+            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cubeButtonActionPerformed"/>
+          </Events>
+        </Component>
+        <Component class="javax.swing.JToggleButton" name="planeButton">
+          <Properties>
+            <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
+              <ComponentRef name="toggleButtonGroup"/>
+            </Property>
+            <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/plane.png"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/materials/multiview/widgets/Bundle.properties" key="MaterialPreviewWidget.planeButton.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/materials/multiview/widgets/Bundle.properties" key="MaterialPreviewWidget.planeButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="focusable" type="boolean" value="false"/>
+            <Property name="horizontalAlignment" type="int" value="4"/>
+            <Property name="horizontalTextPosition" type="int" value="0"/>
+            <Property name="verticalTextPosition" type="int" value="3"/>
+          </Properties>
+          <Events>
+            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="planeButtonActionPerformed"/>
+          </Events>
+        </Component>
+      </SubComponents>
+    </Container>
+  </SubComponents>
+</Form>

+ 234 - 0
jme3-materialeditor/src/com/jme3/gde/materials/multiview/widgets/MaterialPreviewWidget.java

@@ -0,0 +1,234 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/*
+ * MaterialPreviewWidget.java
+ *
+ * Created on 1 août 2011, 10:27:05
+ */
+package com.jme3.gde.materials.multiview.widgets;
+
+import com.jme3.asset.MaterialKey;
+import com.jme3.gde.core.assets.ProjectAssetManager;
+import com.jme3.gde.core.scene.PreviewRequest;
+import com.jme3.gde.core.scene.SceneApplication;
+import com.jme3.gde.core.scene.SceneListener;
+import com.jme3.gde.core.scene.SceneRequest;
+import com.jme3.material.Material;
+import com.jme3.math.FastMath;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.shape.Box;
+import com.jme3.scene.shape.Quad;
+import com.jme3.scene.shape.Sphere;
+import com.jme3.util.TangentBinormalGenerator;
+import javax.swing.ImageIcon;
+
+/**
+ *
+ * @author Nehon
+ */
+public class MaterialPreviewWidget extends javax.swing.JPanel implements SceneListener {
+
+    private Geometry sphere;
+    private Geometry box;
+    private Geometry quad;
+    private Geometry currentGeom;
+    private Material currentMaterial;
+    private boolean init=false;
+
+    /** Creates new form MaterialPreviewWidget */
+    public MaterialPreviewWidget() {
+        initComponents();        
+    }
+
+    private  void initWidget() {
+        SceneApplication.getApplication().addSceneListener(this);
+        Sphere sphMesh = new Sphere(32, 32, 2.5f);
+        sphMesh.setTextureMode(Sphere.TextureMode.Projected);
+        sphMesh.updateGeometry(32, 32, 2.5f, false, false);
+        TangentBinormalGenerator.generate(sphMesh);
+        sphere = new Geometry("previewSphere", sphMesh);
+        sphere.setLocalRotation(new Quaternion().fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_X));
+
+        Box boxMesh = new Box(new Vector3f(0, 0, 0), 1.75f, 1.75f, 1.75f);
+        TangentBinormalGenerator.generate(boxMesh);
+        box = new Geometry("previewBox", boxMesh);
+        box.setLocalRotation(new Quaternion().fromAngleAxis(-FastMath.DEG_TO_RAD * 30, Vector3f.UNIT_X).multLocal(new Quaternion().fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_Y)));
+
+        Quad quadMesh = new Quad(4.5f, 4.5f);
+        TangentBinormalGenerator.generate(quadMesh);
+        quad = new Geometry("previewQuad", quadMesh);
+        quad.setLocalTranslation(new Vector3f(-2.25f, -2.25f, 0));
+
+        currentGeom = sphere;
+        sphereButton.setSelected(true);
+        init=true;
+    }
+
+    @SuppressWarnings("unchecked")
+    public void showMaterial(ProjectAssetManager assetManager, String materialFileName) {
+        if(!init){
+            initWidget();
+        }
+        try {
+            MaterialKey key = new MaterialKey(assetManager.getRelativeAssetPath(materialFileName));
+            assetManager.deleteFromCache(key);
+            Material mat = (Material) assetManager.loadAsset(key);
+            if (mat != null) {
+                currentMaterial = mat;
+                doShowMaterial(mat);
+            }
+        } catch (Exception e) {
+        }
+    }
+
+    private void doShowMaterial(Material m) {
+
+//        geom.setLocalTranslation(-2.5f, -2.5f, 0);
+//        geom.lookAt(new Vector3f(5, 5, 5), Vector3f.UNIT_Y);
+        currentGeom.setMaterial(m);
+        if (currentGeom.getMaterial() != null) {
+            PreviewRequest request = new PreviewRequest(this, currentGeom);
+            request.getCameraRequest().setLocation(new Vector3f(0, 0, 7));
+            request.getCameraRequest().setLookAt(new Vector3f(0, 0, 0), Vector3f.UNIT_Y);
+            SceneApplication.getApplication().createPreview(request);
+        }
+    }
+
+    public void clear() {
+        previewLabel.setIcon(null);
+    }
+
+    public void sceneRequested(SceneRequest request) {
+    }
+
+    public boolean sceneClose(SceneRequest request) {
+        return true;
+    }
+
+    public void cleanUp(){
+         SceneApplication.getApplication().removeSceneListener(this);
+    }
+    
+    public void previewRequested(PreviewRequest request) {        
+        if (request.getRequester() == this) {
+            final ImageIcon icon = new ImageIcon(request.getImage());
+            java.awt.EventQueue.invokeLater(new Runnable() {
+
+                public void run() {
+                    previewLabel.setIcon(icon);
+                }
+            });
+        }
+    }
+
+    /** 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.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        toggleButtonGroup = new javax.swing.ButtonGroup();
+        previewLabel = new javax.swing.JLabel();
+        jToolBar1 = new javax.swing.JToolBar();
+        sphereButton = new javax.swing.JToggleButton();
+        cubeButton = new javax.swing.JToggleButton();
+        planeButton = new javax.swing.JToggleButton();
+
+        previewLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
+        previewLabel.setText(org.openide.util.NbBundle.getMessage(MaterialPreviewWidget.class, "MaterialPreviewWidget.previewLabel.text")); // NOI18N
+
+        jToolBar1.setFloatable(false);
+        jToolBar1.setRollover(true);
+
+        toggleButtonGroup.add(sphereButton);
+        sphereButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/jme3/gde/materials/multiview/widgets/icons/sphere.png"))); // NOI18N
+        sphereButton.setSelected(true);
+        sphereButton.setText(org.openide.util.NbBundle.getMessage(MaterialPreviewWidget.class, "MaterialPreviewWidget.sphereButton.text")); // NOI18N
+        sphereButton.setToolTipText(org.openide.util.NbBundle.getMessage(MaterialPreviewWidget.class, "MaterialPreviewWidget.sphereButton.toolTipText")); // NOI18N
+        sphereButton.setFocusable(false);
+        sphereButton.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
+        sphereButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+        sphereButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
+        sphereButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                sphereButtonActionPerformed(evt);
+            }
+        });
+        jToolBar1.add(sphereButton);
+
+        toggleButtonGroup.add(cubeButton);
+        cubeButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/jme3/gde/materials/multiview/widgets/icons/box.png"))); // NOI18N
+        cubeButton.setText(org.openide.util.NbBundle.getMessage(MaterialPreviewWidget.class, "MaterialPreviewWidget.cubeButton.text")); // NOI18N
+        cubeButton.setToolTipText(org.openide.util.NbBundle.getMessage(MaterialPreviewWidget.class, "MaterialPreviewWidget.cubeButton.toolTipText")); // NOI18N
+        cubeButton.setFocusable(false);
+        cubeButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+        cubeButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
+        cubeButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                cubeButtonActionPerformed(evt);
+            }
+        });
+        jToolBar1.add(cubeButton);
+
+        toggleButtonGroup.add(planeButton);
+        planeButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/jme3/gde/materials/multiview/widgets/icons/plane.png"))); // NOI18N
+        planeButton.setText(org.openide.util.NbBundle.getMessage(MaterialPreviewWidget.class, "MaterialPreviewWidget.planeButton.text")); // NOI18N
+        planeButton.setToolTipText(org.openide.util.NbBundle.getMessage(MaterialPreviewWidget.class, "MaterialPreviewWidget.planeButton.toolTipText")); // NOI18N
+        planeButton.setFocusable(false);
+        planeButton.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
+        planeButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+        planeButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
+        planeButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                planeButtonActionPerformed(evt);
+            }
+        });
+        jToolBar1.add(planeButton);
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(previewLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 120, Short.MAX_VALUE)
+            .addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, 120, Short.MAX_VALUE)
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+                .addComponent(previewLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 120, Short.MAX_VALUE)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE))
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+private void sphereButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sphereButtonActionPerformed
+    currentGeom = sphere;
+    doShowMaterial(currentMaterial);
+}//GEN-LAST:event_sphereButtonActionPerformed
+
+private void cubeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cubeButtonActionPerformed
+    currentGeom = box;
+    doShowMaterial(currentMaterial);
+}//GEN-LAST:event_cubeButtonActionPerformed
+
+private void planeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_planeButtonActionPerformed
+    currentGeom = quad;
+    doShowMaterial(currentMaterial);
+}//GEN-LAST:event_planeButtonActionPerformed
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JToggleButton cubeButton;
+    private javax.swing.JToolBar jToolBar1;
+    private javax.swing.JToggleButton planeButton;
+    private javax.swing.JLabel previewLabel;
+    private javax.swing.JToggleButton sphereButton;
+    private javax.swing.ButtonGroup toggleButtonGroup;
+    // End of variables declaration//GEN-END:variables
+}

BIN
jme3-materialeditor/src/com/jme3/gde/materials/multiview/widgets/icons/box.png


BIN
jme3-materialeditor/src/com/jme3/gde/materials/multiview/widgets/icons/plane.png


BIN
jme3-materialeditor/src/com/jme3/gde/materials/multiview/widgets/icons/sphere.png