Hallo!
Für meine Lernplattform versuche ich mich gerade am Animieren von Swing-Elementen. Momentan bin ich soweit, dass ich eine JLayeredPane habe, die ich um einige Methoden zum Animieren der Komponenten erweitert habe, sowie eine Thread-Subclass fürs Ausführen der Animation. Ziel soll sein, eine Komponente von einer der 4 Seiten ins Bild zu schieben, und das möglichst ruckelfrei. Aktuell funktioniert das Einblenden auch, aber die Zeiten stimmen nicht, das ganze dauert etwa 8 Sekunden, wenn ich auf 1000ms stelle und ruckelt wie sonstwas.
Hier der Quellcode der JLayeredPane (JAnimLayeredPane.java)
Und hier der Quellcode der Animation (Animation.java)
Wäre toll, wenn ihr mir sagen könntet, was ich anders machen muss.
Danke!
Für meine Lernplattform versuche ich mich gerade am Animieren von Swing-Elementen. Momentan bin ich soweit, dass ich eine JLayeredPane habe, die ich um einige Methoden zum Animieren der Komponenten erweitert habe, sowie eine Thread-Subclass fürs Ausführen der Animation. Ziel soll sein, eine Komponente von einer der 4 Seiten ins Bild zu schieben, und das möglichst ruckelfrei. Aktuell funktioniert das Einblenden auch, aber die Zeiten stimmen nicht, das ganze dauert etwa 8 Sekunden, wenn ich auf 1000ms stelle und ruckelt wie sonstwas.
Hier der Quellcode der JLayeredPane (JAnimLayeredPane.java)
Java:
package componentLib;
import java.awt.Component;
import javax.swing.JLayeredPane;
import threads.Animation;
/**
* Subclass der JLayeredPane mit Animationsmöglichkeiten für Komponenten von den
* 4 Seiten der Komponente aus
*
* Funktionsweise: Der Layer 0 enthält alle Komponenten, bis auf die aktuelle
* (diese befindet sich auf Layer 1). Diese sind jedoch alle unsichtbar. Wird
* die oberste Komponente neu gesetzt, so wird die alte oberste Komponente auf
* den Layer 0 gesetzt, die neue auf 1, jedoch außerhalb der Anzeigefläche. Dann
* startet die Animation, die die Komponente fließend in den Anzeigebereich
* schiebt. Anschließend wird die auf Layer 0 gesetzte Komponente, da sie jetzt
* von der animierten Komponente überlagert wird, unsichtbar gemacht.
*
* @author renwal
* @version 1.0.0
*
*/
public class JAnimLayeredPane extends JLayeredPane {
// Konstanten für die Animationsrichtung
public static final int ANIMATION_DIRECTION_TOP = Animation.ANIMATION_DIRECTION_TOP;
public static final int ANIMATION_DIRECTION_BOTTOM = Animation.ANIMATION_DIRECTION_BOTTOM;
public static final int ANIMATION_DIRECTION_LEFT = Animation.ANIMATION_DIRECTION_LEFT;
public static final int ANIMATION_DIRECTION_RIGHT = Animation.ANIMATION_DIRECTION_RIGHT;
// Die momentan oberste Komponente
private Component topmostComponent;
private static final long serialVersionUID = 4551703726681564670L;
public JAnimLayeredPane()
{
// Neue Instanz der JAnimLayeredPane erzeugen
super();
}
/**
* Methode zum Einstellen der obersten Komponente
*
* @param component
* Die Komponente, die als oberste Komponente definiert wird
*/
private void setTopmostComponent(Component component)
{
if (topmostComponent != null)
// Zusätzliche Schritte, wenn bereits eine Komponente "topmost" ist
// Die Komponente auf die unterste Ebene setzen
setLayer(topmostComponent, 0);
// Die neue Komponente "nach vorn holen" und einblenden
setLayer(component, 1);
component.setVisible(true);
// Die neue oberste Komponente setzen
topmostComponent = component;
}
/**
* Methode zum Einblenden der neuen obersten Komponente
*
*
* @param component
* Die neue oberste Komponente
* @param animation
* Die Animationsrichtung
* @param speed
* Die Dauer der Animation in ms
*/
public void animatedShowComponent(Component component, int animation,
int speed)
{
// Parameter auf Korrektheit prüfen
if (component == null)
throw new NullPointerException();
if (animation < 1 || animation > 4)
throw new IllegalArgumentException("Unknown animation direction: "
+ animation);
// Start- und Zielpunkt einstellen
final int to = 0;
final int from = -component.getHeight();
// Neue oberste Komponente dorthin schieben (dann befindet sie
// sich vollständig außerhalb des Anzeigebereiches
component.setLocation(0, from);
// Je nach Animationsrichtung einstellen, ob die Komponente an der
// x-Achse oder an der y-Achse "entlanggeschoben" werden soll
final int track = animation == ANIMATION_DIRECTION_BOTTOM
|| animation == ANIMATION_DIRECTION_TOP ? component.getX()
: component.getY();
// Alte oberste Komponente merken
final Component oldTopmost = topmostComponent;
// Neue oberste Komponente auf den oberen Layer setzen
setTopmostComponent(component);
// Animation starten
new Animation(component, oldTopmost, animation, speed, from, to, track)
.start();
}
@Override
public Component add(Component component)
{
// Überschriebene superclass-Methode für das Hinzufügen von
// Komponenten, um dafür zu sorgen, dass Komponenten nach
// dem Hinzufügen immer invisible sind.
final Component returnComponent = super.add(component);
component.setVisible(false);
return returnComponent;
}
}
Und hier der Quellcode der Animation (Animation.java)
Java:
package threads;
import java.awt.Component;
/**
* Subclass von Thread zur Ausführung einer Animation einer Komponente
*
* @author Rene
* @version 1.0.0
*/
public class Animation extends Thread {
// Konstanten für die Animationsrichtung
public static final int ANIMATION_DIRECTION_TOP = 1;
public static final int ANIMATION_DIRECTION_BOTTOM = 2;
public static final int ANIMATION_DIRECTION_LEFT = 3;
public static final int ANIMATION_DIRECTION_RIGHT = 4;
Component component;
Component underlayingComponent;
int animation;
int speed;
int from;
int to;
int track;
/**
*
* @param component
* Die zu animierende Komponente
* @param underlayingComponent
* Die Komponente, die von der Animation später verdeckt wird und
* dann ausgeblendet werden kann
* @param animation
* Die Animationsrichtung
* @param speed
* Die Animationsdauer in ms
* @param from
* Der Startpunkt der Animation
* @param to
* Der Zielpunkt der Animation
* @param track
* Der Punkt auf der (je nach Animationsrichtung) x- oder
* y-Achse, an dem die Komponente "entlanggeschoben" wird
*/
public Animation(Component component, Component underlayingComponent,
int animation, int speed, int from, int to, int track)
{
// Neue Instanz der Animations-Klasse erzeugen
super();
// Parameter auf Korrektheit prüfen
if (to - from <= 0)
throw new IllegalArgumentException(
"to - from has to be greater than 0!");
if (speed == 0)
throw new IllegalArgumentException("speed must not be 0");
// Parameter übernehmen
this.component = component;
this.underlayingComponent = underlayingComponent;
this.animation = animation;
this.speed = speed;
this.from = from;
this.to = to;
this.track = track;
}
@Override
public void run()
{
// Pausenzeit berechnen
final int pause = speed / (to - from);
System.out.println("speed:" + speed + "; pixels: " + (to - from)
+ "; pause: " + pause);
// Aktuellen Punkt mit Startpunkt vordefinieren
int now = from;
// Je nach Animationsrichtung die Komponente per Schleife an
// ihre neue Position verschieben
if (animation == ANIMATION_DIRECTION_BOTTOM)
while (now < to)
{
now++;
component.setLocation(track, now);
try
{
Thread.sleep(pause);
}
catch (final InterruptedException interrupt)
{
interrupt();
break;
}
}
else if (animation == ANIMATION_DIRECTION_TOP)
while (now > to)
{
now--;
component.setLocation(track, now);
try
{
Thread.sleep(pause);
}
catch (final InterruptedException interrupt)
{
interrupt();
break;
}
}
else if (animation == ANIMATION_DIRECTION_RIGHT)
while (now < to)
{
now++;
component.setLocation(now, track);
try
{
Thread.sleep(pause);
}
catch (final InterruptedException interrupt)
{
interrupt();
break;
}
}
else if (animation == ANIMATION_DIRECTION_LEFT)
while (now > to)
{
now--;
component.setLocation(now, track);
try
{
Thread.sleep(pause);
}
catch (final InterruptedException interrupt)
{
interrupt();
break;
}
}
else
// Wenn als Animationsrichtung keine der 4 verfügbaren angegeben
// wurde
throw new IllegalArgumentException(
"unknown animation direction parameter");
// Wenn eine Komponente als unter der Animation liegend angegeben
// wurde, diese ausblenden, weil sie jetzt sowieso von der animierten
// Komponente verdeckt wird
if (underlayingComponent != null)
underlayingComponent.setVisible(false);
}
}
Wäre toll, wenn ihr mir sagen könntet, was ich anders machen muss.
Danke!