In meiner letzten GWT-Webanwendung ging es unter anderem um die Animation von grafischen Elementen. Zum Beispiel sollten U-Bahnen in einem U-Bahnnetz dargestellt werden und der Nutzer sollte die Animation für einen selbstgewählten Zeitraum abspielen können. So sollten z.B. alle U-Bahnen, die zwischen 6 Uhr und 10 Uhr morgens eine bestimmte Station passieren, animiert werden. Diese Animationen habe ich mit JavaScript gebaut. Die Steuerung der Animationen wollte ich jedoch mit GWT-Elementen in die Anwendung einbauen. Dazu brauchte ich Buttons zum Starten und Stoppen der Animation, sowie eine Zeitanzeige, die den Fortschritt der Animation darstellt. Ich war mir ziemlich sicher, daß dies eine Standardfunktion ist, für die es passende Bibliotheken gibt.
Vorhandene Bibliotheken für einen GWT-Slider
Nach langwierigen Recherchen für diesen Anwendungsfall bin ich jedoch nicht fündig geworden. GWT bietet von sich aus keine fertigen Slideranimationen an. Es gibt zwar eine SliderBar im Inkubator, aber diese ist bisher nicht in die offizielle Bibliothek aufgenommen worden.
Ausprobiert habe ich unter anderem die gwt-slider-bar-Bibliothek. Dies ging zwar in die richtige Richtung, aber der Overhead zum Installieren und Benutzen der Bibliothek war relativ groß und die grafische Umsetzung gefiel mir auch nicht besonders. Diese ist zwar komplett in CSS konfigurierbar, aber dann ist der Nutzen der Bibliothek insgesamt relativ gering. Ein Entwickler von devbliss bietet übrigens einen Cleanup dieser Bibliothek an, mit einer Mavenintegration und besserer Usability der CSS-Styles.
Schöne Slider gibt es von JQuery oder anderen JavaScript-Bibliotheken. Eine gute Lösung zur Einbindung eines JQuery-Sliders in GWT wird hier vorgestellt.
Aber moment mal: ich wollte doch eigentlich in GWT mit Java programmieren! Die Integration von JavaScript in GWT ist immer etwas umständlich und man muss die JSNI-Methoden verwenden. Ich kam also zu dem Schluss, dass es einfacher ist, einen eigenen Slider mit den vorhandenen GWT-Elementen zu bauen. Da dies einwandfrei und relativ flott funktioniert hat, möchte ich euch diese Variante hier vorstellen.
Grafische Elemente des TigerTech TimeSliders
Ein Slider besteht aus den folgenden Elementen: einem Hauptpanel, in welchem sich der Slider bewegt, einem SliderHandle, der von links nach rechts wandert und jeweils einem Panel auf der linken sowie der rechten Seite des SliderHandles, deren Größe sich während der Animation ändert.
Die Animation besteht daraus, dass über eine möglichst große Anzahl von Schritten der linke Slider größer und der rechte Slider kleiner wird. Der SliderHandle bleibt immer in der Mitte der beiden. Dafür brauche ich folgende GWT-Elemente:
- 1x GWT-DecoratorPanel, wenn man schicke abgerundete Ecken will und darin ein HorizontalPanel
- 2x FlowPanel für den rechten und den linken Slider
- 1x FlowPanel für den SliderHandle
- 1x HorizontalPanel für den Tick-Container
- 4x Label für die Tickanzeige
Damit habe ich die grafischen Komponenten auch schon beisammen, gebe noch die gewünschte Größe und Farbe der Elemente an und speichere das Ganze in der Klasse TimeSlider.java ab.
Animieren des TimeSliders
Um den Slider zu animieren, hat die Klasse TimeSlider eine Funktion moveSlider(). Diese bekommt einen Wert übergeben, der sich innerhalb des Spektrums des Sliders befindet und passt die Größe der Elemente entsprechend diesem Wert an. Der SliderHandle bekommt als Tooltip das aktuelle Datum übergeben.
public void moveSlider(int counter, String currentTime){ Double maxTime = new Double(numberOfTimeValues); double position =(440 / maxTime); position = position * counter; int handlePosition = new Double(Math.round(position)).intValue(); if(handlePosition < 435){ leftSlider.setWidth(handlePosition + "px"); rightSlider.setWidth(440 - handlePosition - 5 + "px"); } sliderHandle.setTitle(currentTime); }
Um den TimeSlider bedienen zu können wird drumherum noch ein AnimationPanel gebaut, in welchem sich die Steuerungselemente der Anwendung sowie der TimeSlider selbst befinden.
Außerdem werden Testdaten in Form von Zeitstempeln benötigt, die aus einer Datenbank kommen können. Für die Testanwendung werden sie in einer Klasse TestData erzeugt und in einem Array abgespeichert.
Mit der Hauptklasse GWT_TimeSlider.java wird die Anwendung gestartet. Hier wird ein Objekt des AnimationPanels, das den TimeSlider enthält, sowie ein Objekt für die Testdaten erstellt. Es wird ein Timer erzeugt, der so oft aufgerufen wird, wie Elemente in den Testdaten existieren. Bei jedem Aufruf des Timers wird die moveSlider()-Funktion des TimeSliders aufgerufen und der Slider auf den neuen Wert gesetzt. Damit es eine flüssige Animation wird, sollten genug Testdaten vorhanden sein und die Abstände in welchen der Timer aufgerufen wird nicht zu lang sein. Für die Testanwendung wurden 50 Millisekunden gewählt, was einen smoothen Ablauf garantiert. Dieser Wert wird durch die SpeedUp und SpeedDown-Buttons des AnimationPanels verändert.
//start new timer to schedule animation of timeslider timeTimer = new Timer() { @Override public void run() { timerIsRunning = true; //add current time to the timeslider in the toolbox currentTime = testData.getTimeBounds().get(timeCounter); cb.setText(DateTimeFormat.getFormat(DateTimeFormat.PredefinedFormat.DATE_TIME_MEDIUM).format(currentTime)); ts.moveSlider(timeCounter, DateTimeFormat.getFormat(DateTimeFormat.PredefinedFormat.DATE_TIME_MEDIUM).format(currentTime)); //stop timer if time bounds are reached if (timeCounter== maxTime) { cancel(); timerIsRunning = false; timeCounter = 0; animationPanel.resetAnimationPanel(); return; } timeCounter++; } }; timeTimer.scheduleRepeating(speed);
Die GWT-Anwendung besteht damit aus 4 einfachen Java-Klassen, einer HTML-Seite und ein paar Icons für die Bedienelemente.
Screenshots
In den folgenden 3 Screenshots ist die Test-Anwendung vor dem Start der Animation, während der Animation und in pausiertem Zustand zu sehen.
Download der Test-Anwendung
Die Anwendung kann über meinen Account bei SourceForge heruntergeladen und ausprobiert werden => http://sourceforge.net/projects/gwttimeslider
Viel Spaß!
Links:
- http://code.google.com/p/gwt-slider-bar/
- Cleaned up version of gwt-slider-bar: https://www.devbliss.com/de/gwt-slider-bar-cleanup/
- http://code.google.com/p/google-web-toolkit-incubator/wiki/SliderBar
- http://www.zackgrossbart.com/hackito/gwt-slider/
- http://de-water-talks.blogspot.de/2013/03/gwt-slider.html