8 Okt, 2010 von Tobias Schlecht 1
GoogleMap Vaadin Widget (Google Maps JavaScript API V3)
Wer gerade dabei ist, eine Anwendung mit dem Web Application Framework Vaadin zu realisieren und darüber hinaus beabsichtigt, Google Maps in sein User Interface zu integrieren, hat mehrere Möglichkeiten.
Am naheliegendsten ist es zweifellos, einfach das fertige Vaadin Add-on GoogleMapWidget von Henri Muurimaa dafür zu nutzen, welches die Google Maps JavaScript API V2 einsetzt. Wenn man nun allerdings nicht nur die grundlegenden Funktionalitäten benötigt, kommt die Frage auf, ob man Anpassungen an diesem Widget vornehmen oder ein komplett neues Widget implementieren will.
Für den Fall, dass man sich dazu entschieden hat, ein eigenes Widget zu entwickeln, wäre es natürlich unsinnig, dafür noch die alte API Version und nicht die aktuelle Version, nämlich die Google Maps JavaScript API V3, zu verwenden.
Die meisten Entwickler möchten an dieser Stelle jedoch vermutlich kein JavaScript benutzen, da es ja einer der großen Vorteile von Vaadin ist, dass man die gesamte Anwendung in Java implementieren kann.
Also begibt man sich auf die Suche nach einer passenden GWT Library, welche Java Wrapper für die JavaScript API bereitstellt. Auf einer der offiziellen Seiten über die GWT APIs wird man dann aber schnell durch folgende Aussage enttäuscht: “At the present time, the gwt-maps API only supports Google Maps API version 2.”
Jetzt hat man zwei Möglichkeiten: Entweder man wartet bis Google offiziell eine Library für die Version 3 zur Verfügung stellt, wozu es allerdings keine genauen Angaben gibt, wann das geschehen soll, oder aber man verwendet einfach die Alpha-Version der besagten GWT Library, die auf einer inoffiziellen Seite von Google zu finden ist.
Wer genug Zeit zum Warten und sich aus diesem Grund für die erste Möglichkeit ent- schlossen hat, braucht nun eigentlich nicht mehr weiterzulesen ;-) Allen Anderen soll nachstehend am Beispielprojekt IOException gezeigt werden, wie man das Grundgerüst für sein eigenes GoogleMap Vaadin Widget mit Hilfe der GWT Library gwt-google-maps-v3 (Alpha-Version) erstellt.
Anmerkung: Im Folgenden werden lediglich die essenziellen Schritte aufgeführt. Für die Grundlagen zur Erstellung eines Vaadin Projekts wird auf das Book of Vaadin verwiesen, das vor allem für Anfänger sehr empfehlenswert ist.
Zuerst erzeugt man ein gewöhnliches Vaadin Projekt und legt daraufhin die im Screenshot dargestellte Projektstruktur an. Die JAR-Datei gwt-maps3-0.2b.jar (GWT Library) kann in der Rubrik Downloads der bereits erwähnten inoffiziellen Seite von Google heruntergeladen werden.
MANIFEST.MF
Manifest-Version: 1.0 Vaadin-Widgetsets: de.ioexception.widgets.MainWidgetset.gwt.xml
In der Manifest-Datei muss durch das Attribut Vaadin-Widgetsets
angegeben werden, wo sich der oberste GWT Modul Descriptor befindet, welcher das zentrale Widget Set definiert und auch als Einstiegspunkt zum Kompilieren dient.
web.xml (Ausschnitt)
<init-param> <param-name>widgetset</param-name> <param-value>de.ioexception.widgets.MainWidgetset</param-value> </init-param>
Dies muss zusätzlich im Deployment Descriptor als <init-param>
innerhalb der <servlet>
-Tags aufgeführt werden.
MainWidgetset.gwt.xml (Ausschnitt)
<module> <inherits name="com.vaadin.terminal.gwt.DefaultWidgetSet" /> <inherits name="de.ioexception.widgets.googlemap.GoogleMapWidgetset" /> </module>
Wie bereits erwähnt, wird in der Datei MainWidgetset.gwt.xml das zentrale Widget Set definiert. Dazu wird erst einmal vom Default Widget Set und anschließend von den GWT Modul Descriptoren der einzelnen Widget Sets geerbt. Da
das gezeigte Beispielprojekt jedoch nur das GoogleMap Widget beinhaltet, ist dies hier auch die einzige Angabe.
GoogleMapWidgetset.gwt.xml (Ausschnitt)
<module> <inherits name="com.vaadin.terminal.gwt.DefaultWidgetSet" /> <inherits name="com.google.gwt.maps.Maps" /> <script src="http://maps.google.com/maps/api/js?sensor=false" /> <source path="client" /> </module>
Um die JAR-Datei gwt-maps3-0.2b.jar (GWT Library) einzubeziehen, muss von deren GWT Modul Descriptor geerbt werden. Dies geschieht durch <inherits name="com.google.gwt.maps.Maps" />
. Durch den <script>
-Tag erhält man Zugriff auf die Google Maps JavaScript API. Anschließend wird noch der Pfad, an dem sich die clientseitigen Dateien befinden, definiert.
GoogleMap.java
package de.ioexception.widgets.googlemap.server; import java.util.Map; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; import com.vaadin.ui.AbstractComponent; import com.vaadin.ui.ClientWidget; import de.ioexception.widgets.googlemap.client.VGoogleMap; @ClientWidget(VGoogleMap.class) public class GoogleMap extends AbstractComponent { @Override public void paintContent(PaintTarget target) throws PaintException { super.paintContent(target); } @Override public void changeVariables(Object source, Map<String, Object> variables) { super.changeVariables(source, variables); } }
Die Klasse GoogleMap.java ist an dieser Stelle nur der Vollständigkeit halber aufgeführt und bedarf eigentlich keiner weiteren Erklärung, da dies der gewöhnliche Aufbau einer serverseitigen Widget-Klasse ist und erst einmal nicht erweitert werden muss.
VGoogleMap.java
package de.ioexception.widgets.googlemap.client; import com.google.gwt.maps.client.base.LatLng; import com.google.gwt.maps.client.MapOptions; import com.google.gwt.maps.client.MapTypeId; import com.google.gwt.maps.client.MapWidget; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.SimplePanel; import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.Paintable; import com.vaadin.terminal.gwt.client.UIDL; public class VGoogleMap extends Composite implements Paintable { private SimplePanel wrapperPanel = null; private MapWidget mapWidget = null; private MapOptions mapOptions = null; public VGoogleMap() { wrapperPanel = new SimplePanel(); initWidget(wrapperPanel); } @Override public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { if(mapWidget == null) { initMap(); } } private void initMap() { mapOptions = new MapOptions(); mapOptions.setZoom(17); mapOptions.setCenter(new LatLng(48.42285529218286, 9.957287907600403)); mapOptions.setMapTypeId(new MapTypeId().getSatellite()); mapOptions.setScrollwheel(true); mapOptions.setDraggable(true); mapOptions.setNavigationControl(true); mapOptions.setMapTypeControl(true); mapWidget = new MapWidget(mapOptions); mapWidget.setWidth("800px"); mapWidget.setHeight("500px"); wrapperPanel.add(mapWidget); } }
In der clientseitigen Widget-Klasse ist zu sehen, dass ein MapWidget
nur mit MapOptions
als Parameter initialisiert werden kann. Verpflichtend sind Werte zu den Eigenschaften center, mapTypeId und zoom. Im Absatz MapOptions der Google Maps JavaScript API V3 kann dies nachgelesen werden.
IOException.java
package de.ioexception; import com.vaadin.Application; import com.vaadin.ui.Window; import de.ioexception.widgets.googlemap.server.GoogleMap; public class IOException extends Application { @Override public void init() { Window mainWindow = new Window("IOException"); GoogleMap googleMap = new GoogleMap(); mainWindow.addComponent(googleMap); setMainWindow(mainWindow); } }
Wie hier zu sehen ist, kann das GoogleMap Widget nun völlig unkompliziert verwendet werden. Als Beispiel dient dafür die Anwendungsklasse IOException
, in der das initialisierte Widget einfach zum Main Window hinzugefügt wird.