# Fließende Bewegung von Graphics



## raGe666 (10. Jul 2012)

Hi,

ich hab noch eine Frage zu dem ganzen Graphicszeug. Und zwar möchte ich auf Knopfdruck eine Ellipse verschieben, ohne dass diese sofort dorthin spring, sondern eben dorthin "fließt". Dabei denke ich an die Animation von Pacman, der von Zelle zu Zelle "läuft" und eben nicht auf einmal in einer Zelle verschwindet und in der nächsten Zelle wieder auftaucht.
Das hab ich im Moment so umgesetzt, dass bei Tastendruck ein Timer mit 10ms delay gestartet wird und er so die Position x um 1 vergrößert, bis sie insgesamt um zB 50 Pixel verschoben wurde. Jetzt kommt mir das sehr umständlich und auch ziemlich hässlich vor. Wird das denn "normalerweise" auch so gemacht, oder gibts da vielleicht Sachen in JavaFX? Oder nimmt man da eigtl. ein animiertes .gif?

Hier mal der Code vom Listener:
[JAVA=89]class MyListener implements ActionListener {
    Test caller;
    int i;
    int dir;

    javax.swing.Timer timer;

    public MyListener(Test o) {
        this.caller = o;
        i = 0;
        timer = new javax.swing.Timer(10, this);
    }


    public void actionPerformed(ActionEvent evt) {
        Object obj = evt.getSource();

        if (obj.equals(caller.button1)) {
            if (caller.pane.y >= 10) {
                i = 0;
                dir = 0;
                timer.start();
                toggleButtons(false);
            }
        } else if (obj.equals(caller.button2)) {
            if (caller.pane.x <= 290) {
                i = 0;
                dir = 1;
                timer.start();
                toggleButtons(false);
            }
        } else if (obj.equals(caller.button3)) {
            if (caller.pane.y <= 290) {
                i = 0;
                dir = 2;
                timer.start();
                toggleButtons(false);
            }
        } else if (obj.equals(caller.button4)) {
            if (caller.pane.x >= 10) {
                i = 0;
                dir = 3;
                timer.start();
                toggleButtons(false);
            }
        } else if (obj.equals(timer)) {
            if (i == 50) {
                timer.stop();
                toggleButtons(true);
            } else {
                if (dir == 0) {
                    caller.pane.y--;
                } else if (dir == 1) {
                    caller.pane.x++;
                } else if (dir == 2) {
                    caller.pane.y++;
                } else if (dir == 3) {
                    caller.pane.x--;
                }
                i++;
            }
        }
        caller.label.setText(caller.pane.x + ", " + caller.pane.y);
        caller.frame.repaint();
    }

    public void toggleButtons(boolean b) {
        caller.button1.setEnabled(b);
        caller.button2.setEnabled(b);
        caller.button3.setEnabled(b);
        caller.button4.setEnabled(b);
    }
}[/code]


----------



## Marco13 (10. Jul 2012)

Das Verfahren an sich ist nicht falsch. (Die Alternative, ohne Timer, ist in http://www.java-forum.org/entwuerfe/113007-kein-swing-tutorial-2.html#post808287 beschrieben, aber beachte auch die nachfolgende Diskussion: Ein Timer ist vielleicht nicht verkehrt).

Das häßliche kommt dort IMHO eher daher, dass alle ActionListener zusammengewurstet sind. Vielleicht kann man das mit einer anonymen inneren Klasse schöner machen

```
timer = new javax.swing.Timer(10, new ActionListener(){
    @Override
    public void actionPerformed(ActionEvent evt) {
        if (i == 50) {
            timer.stop();
            toggleButtons(true);
        } else {    
            pane.x += dx;
            pane.y += dy;
        }
    }
});
```
Ähnlich für die Buttons.


----------



## raGe666 (11. Jul 2012)

Das fand ich immer unschön, dass dann im Folder mehr Dateien erzeugt werden. Aber gut, wenn ichs in ne jar packe, sieht mans ja eh nicht mehr..
Hab gerade in JavaFX reingeschaut, vermutlich ist das, was ich mir weiter aneignen sollte, wenn ich mehr solche Animationen machen will

Danke fürs Feedback


----------



## raGe666 (2. Aug 2012)

Nachtrag: eine sehr informative Seite über (nicht ausschließlich) Animation in Swing sagt, dass Tread effektiver als Swing.Timer ist


----------



## Marco13 (2. Aug 2012)

Effektiv sind beide. Falls 'effizient' gemeint war: Das mag in mancher hinsicht stimmen, aber das sollte man doch etwas differenzierter betrachten...


----------



## raGe666 (3. Aug 2012)

Ja. effizienter ^^
Warum mag das nur in mancher Hinsicht stimmen?


----------



## Marco13 (3. Aug 2012)

Ja, man könnte da sehr lange (und SEHR differenziert) drüber reden. Einmal ist ein neuer Thread eben ein neuer Thread - ggf. kann da etwas echt parallel ablaufen, schließlich haben wir alle QuadCores. Dann verwendet der Swing-Timer intern einen "Scheduling"-Mechanismus, der recht aufwändig ist (um rauszufinden, wer wann als nächstes benachrichtigt werden muss). Er ist nicht sooo aufwändig dass es unbedingt die Performance merklich runterziehen würde, aber - bei einem eigenen Thread fällt es eben weg. Dafür muss man sich bei letzterem Gedanken um die synchronisation machen - und das kann wiederum SEHR kompliziert sein. Insgesamt kann man sagen, dass so ein SwingTimer für vieles SO viel einfacher zu verwenden ist, dass man nur Threads verwenden sollte, wenn es wirklich auf viel Performance, Parallelität (!) und genaue Kontrolle über die Abläufe ankommt.


----------

