Browse Source

SDK : One can now set the animation parameters (loopMode and speed) when playing an animation in the SDK

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9848 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
rem..om 13 years ago
parent
commit
cc9d058614

+ 149 - 35
jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeAnimation.java

@@ -31,9 +31,14 @@
  */
 package com.jme3.gde.core.sceneexplorer.nodes;
 
+import com.jme3.animation.AnimChannel;
 import com.jme3.animation.AnimControl;
+import com.jme3.animation.AnimEventListener;
 import com.jme3.animation.Animation;
+import com.jme3.animation.LoopMode;
+import com.jme3.gde.core.properties.AnimationProperty;
 import com.jme3.gde.core.scene.SceneApplication;
+import com.jme3.gde.core.sceneexplorer.nodes.actions.ChannelDialog;
 import com.jme3.gde.core.sceneexplorer.nodes.actions.impl.tracks.AudioTrackWizardAction;
 import com.jme3.gde.core.sceneexplorer.nodes.actions.impl.tracks.EffectTrackWizardAction;
 import java.awt.Image;
@@ -56,17 +61,20 @@ import org.openide.util.ImageUtilities;
  */
 @org.openide.util.lookup.ServiceProvider(service = SceneExplorerNode.class)
 public class JmeAnimation extends AbstractSceneExplorerNode {
-    
+
     private Animation animation;
     private static final String ICON = "com/jme3/gde/core/sceneexplorer/nodes/icons/anim.png";
     private static final String ICON_PLAY = "com/jme3/gde/core/sceneexplorer/nodes/icons/animPlay.png";
     private Image icon;
     private JmeAnimControl jmeControl;
     private boolean playing = false;
-    
+    private LoopMode animLoopMode = LoopMode.Loop;
+    private float animSpeed = 1.0f;
+    private AnimChannel channel = null;
+
     public JmeAnimation() {
     }
-    
+
     public JmeAnimation(JmeAnimControl control, Animation animation, JmeTrackChildren children, DataObject dataObject) {
         super(children);
         this.dataObject = dataObject;
@@ -79,44 +87,44 @@ public class JmeAnimation extends AbstractSceneExplorerNode {
         children.setAnimation(this);
         children.setAnimControl(jmeControl);
         icon = ImageUtilities.loadImage(ICON);
-        
+
     }
-    
+
     @Override
     public Image getIcon(int type) {
         return icon;
     }
-    
+
     @Override
     public Image getOpenedIcon(int type) {
-        
+
         return icon;
-        
+
     }
-    
+
     public void toggleIcon(boolean enabled) {
         if (!playing) {
             icon = ImageUtilities.loadImage(ICON);
-            
+
         } else {
             icon = ImageUtilities.loadImage(ICON_PLAY);
-            
+
         }
         fireIconChange();
     }
-    
+
     @Override
     public Action getPreferredAction() {
         return Actions.alwaysEnabled(new PlayAction(), "Play", "", false);
-        
+
     }
-    
+
     private void play() {
         playing = !playing;
         toggleIcon(playing);
         jmeControl.setAnim(this);
     }
-    
+
     @Override
     protected Sheet createSheet() {
         //TODO: multithreading..
@@ -128,36 +136,37 @@ public class JmeAnimation extends AbstractSceneExplorerNode {
             return sheet;
         }
 
-        //  set.put(new AnimationProperty(animControl));
+        set.put(new AnimationProperty(jmeControl.getLookup().lookup(AnimControl.class)));
 
         sheet.put(set);
         return sheet;
-        
+
     }
-    
+
     public void setChanged() {
         fireSave(true);
     }
-    
+
     @Override
     public Action[] getActions(boolean context) {
-        
+
         return new Action[]{Actions.alwaysEnabled(new PlayAction(), playing ? "Stop" : "Play", "", false),
+                    Actions.alwaysEnabled(new PlayBackParamsAction(), "Playback parameters", "", false),
                     Actions.alwaysEnabled(new EffectTrackWizardAction(jmeControl.getLookup().lookup(AnimControl.class).getSpatial(), this), "Add Effect Track", "", false),
                     Actions.alwaysEnabled(new AudioTrackWizardAction(jmeControl.getLookup().lookup(AnimControl.class).getSpatial(), this), "Add Audio Track", "", false)
                 };
     }
-    
+
     @Override
     public boolean canDestroy() {
         return false;
     }
-    
+
     public void stop() {
         playing = false;
-        toggleIcon(playing);        
+        toggleIcon(playing);
     }
-    
+
     @Override
     public void destroy() throws IOException {
 //        super.destroy();
@@ -177,61 +186,166 @@ public class JmeAnimation extends AbstractSceneExplorerNode {
 //            Exceptions.printStackTrace(ex);
 //        }
     }
-    
+
     @Override
     public void refresh(boolean immediate) {
         super.refresh(immediate);
         ((JmeTrackChildren) getChildren()).refreshChildren(false);
     }
-    
+
     public Class getExplorerObjectClass() {
         return Animation.class;
     }
-    
+
     @Override
     public Class getExplorerNodeClass() {
         return JmeAnimation.class;
     }
-    
+
     @Override
     public Node[] createNodes(Object key, DataObject key2, boolean cookie) {
         JmeTrackChildren children = new JmeTrackChildren(this, jmeControl);
         JmeAnimation jsc = new JmeAnimation(jmeControl, (Animation) key, children, key2);
         return new Node[]{jsc};
     }
-    
+
     class PlayAction implements ActionListener {
-        
+
         public void actionPerformed(ActionEvent e) {
             final AnimControl control = jmeControl.getLookup().lookup(AnimControl.class);
             if (control == null) {
                 return;
             }
+
             try {
                 SceneApplication.getApplication().enqueue(new Callable<Void>() {
-                    
                     public Void call() throws Exception {
                         if (playing) {
                             control.clearChannels();
+                            channel = null;
                             jmeControl.setAnim(null);
                             return null;
                         }
                         control.clearChannels();
-                        control.createChannel().setAnim(animation.getName());
-                        play();
-                        
+                        channel = control.createChannel();
+                        channel.setAnim(animation.getName());
+                        innerSetLoopMode();
+                        channel.setSpeed(animSpeed);
+                        java.awt.EventQueue.invokeLater(new Runnable() {
+                            public void run() {
+                                play();
+                            }
+                        });
                         return null;
+
                     }
                 }).get();
             } catch (InterruptedException ex) {
                 Exceptions.printStackTrace(ex);
+                return;
             } catch (ExecutionException ex) {
                 Exceptions.printStackTrace(ex);
+                return;
             }
-            
+
         }
     }
+
+    private void innerSetLoopMode() {
+        final AnimControl control = jmeControl.getLookup().lookup(AnimControl.class);
+        channel.setLoopMode(animLoopMode);
+        if (animLoopMode == LoopMode.DontLoop) {
+            control.addListener(new AnimEventListener() {
+                public void onAnimCycleDone(AnimControl ac, AnimChannel ac1, String animName) {
+                    if (animName.equals(animation.getName())) {
+                        if (playing) {
+                            control.clearChannels();
+                            channel = null;
+                            jmeControl.setAnim(null);
+                            java.awt.EventQueue.invokeLater(new Runnable() {
+                                public void run() {
+                                    stop();
+                                }
+                            });                           
+                        }
+
+                        ac.removeListener(this);
+                    }
+                }
+
+                public void onAnimChange(AnimControl ac, AnimChannel ac1, String animName) {
+//                    if (animation.getName().equals(ac1.getAnimationName())) {
+//                         java.awt.EventQueue.invokeLater(new Runnable() {
 //
+//                            public void run() {
+//                                 stop();
+//                            }
+//                        });
+//                    }
+                }
+            });
+        }
+    }
+
+    class PlayBackParamsAction implements ActionListener {
+
+        ChannelDialog dialog = new ChannelDialog(null, false, JmeAnimation.this);
+
+        public void actionPerformed(ActionEvent e) {
+            dialog.setLocationRelativeTo(null);
+            dialog.setVisible(true);
+
+        }
+    }
+
+    public LoopMode getAnimLoopMode() {
+        return animLoopMode;
+    }
+
+    public void setAnimLoopMode(LoopMode loopMode) {
+        this.animLoopMode = loopMode;
+
+        try {
+            SceneApplication.getApplication().enqueue(new Callable<Void>() {
+                public Void call() throws Exception {
+                    if (channel != null) {
+                        innerSetLoopMode();
+                    }
+
+                    return null;
+                }
+            }).get();
+        } catch (InterruptedException ex) {
+            Exceptions.printStackTrace(ex);
+        } catch (ExecutionException ex) {
+            Exceptions.printStackTrace(ex);
+        }
+
+
+    }
+
+    public float getAnimSpeed() {
+        return animSpeed;
+    }
+
+    public void setAnimSpeed(float speed) {
+        this.animSpeed = speed;
+        try {
+            SceneApplication.getApplication().enqueue(new Callable<Void>() {
+                public Void call() throws Exception {
+                    if (channel != null) {
+                        channel.setSpeed(animSpeed);
+                    }
+                    return null;
+                }
+            }).get();
+        } catch (InterruptedException ex) {
+            Exceptions.printStackTrace(ex);
+        } catch (ExecutionException ex) {
+            Exceptions.printStackTrace(ex);
+        }
+
+    }
 //    class AddTrackAction implements ActionListener {
 //
 //        public void actionPerformed(ActionEvent e) {

+ 7 - 0
jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/Bundle.properties

@@ -14,3 +14,10 @@ ParticleInfluencerPicker.jPanel1.border.title=Chose a UserData type
 ParticleInfluencerPicker.jButton2.text=Cancel
 ParticleInfluencerPicker.jButton1.text=Ok
 ParticleInfluencerPicker.jTextField1.text=
+ChannelDialog.jPanel1.border.title=Animation properties
+ChannelDialog.jLabel1.text=Loop mode
+ChannelDialog.jLabel2.text=Speed
+ChannelDialog.jTextField1.text=jTextField1
+ChannelDialog.jButton1.text=Ok
+ChannelDialog.jButton2.text=Cancel
+ChannelDialog.jButton2.actionCommand=Cancel

+ 160 - 0
jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/ChannelDialog.form

@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
+  <Properties>
+    <Property name="defaultCloseOperation" type="int" value="2"/>
+  </Properties>
+  <SyntheticProperties>
+    <SyntheticProperty name="formSizePolicy" type="int" value="1"/>
+  </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="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">
+          <Group type="102" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Component id="jPanel1" alignment="0" max="32767" attributes="0"/>
+                  <Group type="102" alignment="1" attributes="0">
+                      <Component id="jButton2" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace max="32767" attributes="0"/>
+                      <Component id="jButton1" 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="0" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="jPanel1" min="-2" max="-2" attributes="0"/>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="3" attributes="0">
+                  <Component id="jButton1" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="jButton2" alignment="3" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace max="32767" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <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.TitledBorderInfo">
+            <TitledBorder title="Animation properties">
+              <ResourceString PropertyName="titleX" bundle="com/jme3/gde/core/sceneexplorer/nodes/actions/Bundle.properties" key="ChannelDialog.jPanel1.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">
+              <Group type="102" alignment="0" attributes="0">
+                  <EmptySpace min="-2" pref="66" 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 type="separate" max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="0" attributes="0">
+                      <Component id="jComboBox1" pref="142" max="32767" attributes="0"/>
+                      <Component id="jTextField1" max="32767" attributes="0"/>
+                  </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">
+                  <Group type="103" groupAlignment="3" attributes="0">
+                      <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
+                      <Component id="jComboBox1" alignment="3" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace type="separate" max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="3" attributes="0">
+                      <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/>
+                      <Component id="jTextField1" alignment="3" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace min="0" pref="16" max="32767" 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/core/sceneexplorer/nodes/actions/Bundle.properties" key="ChannelDialog.jLabel1.text" 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/core/sceneexplorer/nodes/actions/Bundle.properties" key="ChannelDialog.jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JComboBox" name="jComboBox1">
+          <Properties>
+            <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
+              <StringArray count="3">
+                <StringItem index="0" value="Loop"/>
+                <StringItem index="1" value="DontLoop"/>
+                <StringItem index="2" value="Cycle"/>
+              </StringArray>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JTextField" name="jTextField1">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/core/sceneexplorer/nodes/actions/Bundle.properties" key="ChannelDialog.jTextField1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+      </SubComponents>
+    </Container>
+    <Component class="javax.swing.JButton" name="jButton1">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="com/jme3/gde/core/sceneexplorer/nodes/actions/Bundle.properties" key="ChannelDialog.jButton1.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="jButton1ActionPerformed"/>
+      </Events>
+    </Component>
+    <Component class="javax.swing.JButton" name="jButton2">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="com/jme3/gde/core/sceneexplorer/nodes/actions/Bundle.properties" key="ChannelDialog.jButton2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+        <Property name="actionCommand" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="com/jme3/gde/core/sceneexplorer/nodes/actions/Bundle.properties" key="ChannelDialog.jButton2.actionCommand" 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="jButton2ActionPerformed"/>
+      </Events>
+    </Component>
+  </SubComponents>
+</Form>

+ 185 - 0
jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/ChannelDialog.java

@@ -0,0 +1,185 @@
+ /*
+ *  Copyright (c) 2009-2012 jMonkeyEngine
+ *  All rights reserved.
+ * 
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ * 
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ *  * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ *  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.gde.core.sceneexplorer.nodes.actions;
+
+import com.jme3.animation.LoopMode;
+import com.jme3.gde.core.sceneexplorer.nodes.JmeAnimation;
+
+/**
+ *
+ * @author Nehon
+ */
+
+
+public class ChannelDialog extends javax.swing.JDialog {
+    
+    JmeAnimation jmeAnim;
+
+    /**
+     * Creates new form ChannelDialog
+     */
+    public ChannelDialog(java.awt.Frame parent, boolean modal, JmeAnimation jmeAnim) {
+        super(parent, modal);
+        this.jmeAnim = jmeAnim;
+        initComponents();
+        jTextField1.setText(jmeAnim.getAnimSpeed()+"");
+        jComboBox1.setSelectedItem(jmeAnim.getAnimLoopMode().toString());
+    }
+
+    /**
+     * 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() {
+
+        jPanel1 = new javax.swing.JPanel();
+        jLabel1 = new javax.swing.JLabel();
+        jLabel2 = new javax.swing.JLabel();
+        jComboBox1 = new javax.swing.JComboBox();
+        jTextField1 = new javax.swing.JTextField();
+        jButton1 = new javax.swing.JButton();
+        jButton2 = new javax.swing.JButton();
+
+        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+
+        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ChannelDialog.class, "ChannelDialog.jPanel1.border.title"))); // NOI18N
+
+        org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(ChannelDialog.class, "ChannelDialog.jLabel1.text")); // NOI18N
+
+        org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(ChannelDialog.class, "ChannelDialog.jLabel2.text")); // NOI18N
+
+        jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Loop", "DontLoop", "Cycle" }));
+
+        jTextField1.setText(org.openide.util.NbBundle.getMessage(ChannelDialog.class, "ChannelDialog.jTextField1.text")); // NOI18N
+
+        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
+        jPanel1.setLayout(jPanel1Layout);
+        jPanel1Layout.setHorizontalGroup(
+            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(jPanel1Layout.createSequentialGroup()
+                .addGap(66, 66, 66)
+                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+                    .addComponent(jLabel2)
+                    .addComponent(jLabel1))
+                .addGap(18, 18, 18)
+                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(jComboBox1, 0, 142, Short.MAX_VALUE)
+                    .addComponent(jTextField1))
+                .addContainerGap())
+        );
+        jPanel1Layout.setVerticalGroup(
+            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(jPanel1Layout.createSequentialGroup()
+                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(jLabel1)
+                    .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+                .addGap(18, 18, 18)
+                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(jLabel2)
+                    .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+                .addGap(0, 16, Short.MAX_VALUE))
+        );
+
+        org.openide.awt.Mnemonics.setLocalizedText(jButton1, org.openide.util.NbBundle.getMessage(ChannelDialog.class, "ChannelDialog.jButton1.text")); // NOI18N
+        jButton1.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                jButton1ActionPerformed(evt);
+            }
+        });
+
+        org.openide.awt.Mnemonics.setLocalizedText(jButton2, org.openide.util.NbBundle.getMessage(ChannelDialog.class, "ChannelDialog.jButton2.text")); // NOI18N
+        jButton2.setActionCommand(org.openide.util.NbBundle.getMessage(ChannelDialog.class, "ChannelDialog.jButton2.actionCommand")); // NOI18N
+        jButton2.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                jButton2ActionPerformed(evt);
+            }
+        });
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+        getContentPane().setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+                        .addComponent(jButton2)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                        .addComponent(jButton1)))
+                .addContainerGap())
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(jButton1)
+                    .addComponent(jButton2))
+                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+        );
+
+        pack();
+    }// </editor-fold>//GEN-END:initComponents
+
+    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
+        jmeAnim.setAnimLoopMode(LoopMode.valueOf(jComboBox1.getSelectedItem().toString()));
+        float speed = 1.0f;
+        try{
+            speed = Float.parseFloat(jTextField1.getText());
+        }catch(NumberFormatException e){
+            //wrong format, just setting the speed to 1.0
+        }
+        jmeAnim.setAnimSpeed(speed);
+        setVisible(false);
+    }//GEN-LAST:event_jButton1ActionPerformed
+
+    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
+         setVisible(false);
+    }//GEN-LAST:event_jButton2ActionPerformed
+
+
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JButton jButton1;
+    private javax.swing.JButton jButton2;
+    private javax.swing.JComboBox jComboBox1;
+    private javax.swing.JLabel jLabel1;
+    private javax.swing.JLabel jLabel2;
+    private javax.swing.JPanel jPanel1;
+    private javax.swing.JTextField jTextField1;
+    // End of variables declaration//GEN-END:variables
+}