# Java3D Interaktion während Animation



## cytom2k (7. Nov 2010)

Hallo Forum.

Ich arbeite gerade an einem kleinen Projekt für ein Institut an der Uni zur Visualisierung von Atomenbewegungen. Dabei werden die Atompositionen mit Zeitkoordinate aus  externen Daten in das Prog eingelesen. Die Sicht auf das kleine Atomgitter lässt sich Dank einen Orbitbehavior drehen,zoomen und bewegen.

Die Animation ist so realisiert worden , dass eine Schleife jeweils durch setTransform die Position jedes Atoms im nächsten Schritt verändert. In dieser Schleife selbst ist noch eine Thread.sleep() Anweisung damit die Animation flüssig verläuft.

Das Problem ist nun , dass das Programm erst wieder Benutzeraktionen entgegenen nimmt sobald die Schleife durchlaufen ist,sprich die Animation zu Ende ist. D.h. man kann die Sicht während der Animation nicht verändern. 

Ich habe versucht die Schleife in einen neuen Thread ( innere Klasse) auszulagern. Das Problem bleibt das Selbe. 


Das hier passiert , wenn der PlayButton gedrückt wird.


```
class PlayClick implements ActionListener
  {
    public void actionPerformed(ActionEvent e)
    {
      System.out.println("Play wurde gedrückt");
      
      
      PlayThread b = new PlayThread(arrAtome,atome,laenge,arrTime,arrX,arrY,arrZ);
                           //Die Parameter beinhalten die x,y,z Koordinaten 
                           //arrAtome ist ein Array was die Referenzen auf die Atom-Objekte enthält
                           //atome= Anzahl der Atome , laenge = Länge des Atomgitters 
      b.run();
      
    }
```


Hier ist die PlayThread - Klasse 



```
import java.util.*;
import javax.media.j3d.*;
import javax.vecmath.*;

class PlayThread extends Thread {

        ArrayList<TransformGroup> arrAtome = new ArrayList<TransformGroup>();
        ArrayList<Float> arrTime = new ArrayList<Float>();

        ArrayList<Float> arrX = new ArrayList<Float>();
        ArrayList<Float> arrY = new ArrayList<Float>();
        ArrayList<Float> arrZ = new ArrayList<Float>();
        int atome,stepnummer;
        float zeit;
        int speed=1;
        float laenge;


        public PlayThread(ArrayList<TransformGroup> ArrAtome,int Atome,float Laenge,ArrayList<Float> ArrTime,ArrayList<Float> ArrX,ArrayList<Float> ArrY,ArrayList<Float> ArrZ)
        {
     arrAtome = ArrAtome;
    arrTime = ArrTime;
    arrX = ArrX;
    arrY = ArrY;
    arrZ = ArrZ;
    atome = Atome;
    laenge = Laenge;
    zeit = ArrTime.get((arrTime.size()-1));
        }

    public void run() {

      stepnummer=0;
      
        try {
            for(int i = 0; i < zeit; i++) {
            transform_next();
            Thread.sleep(200/speed);

            }

        }
        catch(InterruptedException e) {
        }
        stepnummer=0;
      }
     
    

     public void transform_next()
  {

            stepnummer++;

            Transform3D tf = new Transform3D();
            Vector3f v ;
            float x = 0;
            float y = 0;
            float z = 0;
           

                for ( int i =atome*stepnummer;i<atome*(stepnummer+1);i++)
                {

                    if (stepnummer<= (int) arrTime.get((arrTime.size()-1)).floatValue())
                    {
                        x= arrX.get(i)*1/laenge;
                        y= arrY.get(i)*1/laenge;
                        z= arrZ.get(i)*1/laenge;
                        v = new Vector3f(-0.5f+x,y-0.5f,-z);
                        tf.set(v);
                        arrAtome.get(i-atome*stepnummer).setTransform(tf);
                    }
                           }
            


  }

  }
```

Hoffe auf gute Anregungen , die weiterhelfen könnten. 

Gruss
cytom


----------



## cytom2k (8. Nov 2010)

Habe im folgendem Thread http://www.java-forum.org/spiele-multimedia-programmierung/107562-keylistener-thread-problem.html eine Lösung für mein Problem gefunden, in dem ich eraaaa's Lösung einfach in meinem Code ersetzt habe. Funktioniert prima, aber ich weiss nicht wieso. 


```
class PlayClick implements ActionListener
  {
    public void actionPerformed(ActionEvent e)
    {
      System.out.println("Play wurde gedrückt");
      
      new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try {
            for(int i = 0; i < zeit; i++) {
            transform_next();
            Thread.sleep(200/speed);

            }

        }
        catch(InterruptedException e) {
        }
        stepnummer=0;  //evtl. auch direkt lieber einen swing-timer benutzen, das erspart auch das sleep rumgegurke :)
                        }
                    }).start();
```


----------



## Marco13 (8. Nov 2010)

Das wäre doch das, was du mit
_Ich habe versucht die Schleife in einen neuen Thread ( innere Klasse) auszulagern. Das Problem bleibt das Selbe. _
versucht haben solltest!? Wie war es denn bei dir? (Anders, falsch, jaja, aber wie genau?  )


----------



## cytom2k (8. Nov 2010)

Marco13 hat gesagt.:


> Das wäre doch das, was du mit
> _Ich habe versucht die Schleife in einen neuen Thread ( innere Klasse) auszulagern. Das Problem bleibt das Selbe. _
> versucht haben solltest!? Wie war es denn bei dir? (Anders, falsch, jaja, aber wie genau?  )



Mit meinem Code hat es nichtgeklappt. D.h. die Animation lief schön vor sich hin , aber währendessen waren keine Benutzerinteraktionen möglich. Sicht drehen wie auch Prog beenden ( auf's X drücken ).

Den Lösung bringenden Thread habe ich schon gestern gefunden , aber habe genauso gedacht wie Du und den Fehler in meinem Code nicht gefunden. Wieso es mit eraaa's Code funktioniert ist mir schleierhaft.


----------

