22
33import com .vaadin .flow .component .UI ;
44import com .vaadin .flow .component .button .Button ;
5- import com .vaadin .flow .component .html .H1 ;
5+ import com .vaadin .flow .component .button .ButtonVariant ;
6+ import com .vaadin .flow .component .html .H2 ;
67import com .vaadin .flow .component .notification .Notification ;
78import com .vaadin .flow .component .orderedlayout .HorizontalLayout ;
89import com .vaadin .flow .component .orderedlayout .VerticalLayout ;
@@ -90,10 +91,12 @@ public class MyTripToCanada extends VerticalLayout {
9091 private JLPolyline currentPath ;
9192
9293 public MyTripToCanada () {
93- setSizeFull ();
94+ setWidthFull ();
95+ setHeight ("100px" );
96+
9497
9598 // Title
96- H1 title = new H1 ( "🌍 My Trip to Canada " );
99+ H2 title = new H2 ( "JL-Map Vaadin Demo " );
97100
98101 // Create the map view
99102 mapView = JLMapView .builder ()
@@ -104,6 +107,7 @@ public MyTripToCanada() {
104107 .startCoordinate (SARI )
105108 .showZoomController (true )
106109 .build ();
110+ mapView .getStyle ().set ("border-radius" , "16px" );
107111
108112 // Control panel
109113 HorizontalLayout controlPanel = new HorizontalLayout ();
@@ -115,8 +119,10 @@ public MyTripToCanada() {
115119 startButton .setEnabled (false );
116120 startJourney ();
117121 });
122+ startButton .addThemeVariants (ButtonVariant .LUMO_PRIMARY );
118123
119124 Button resetButton = new Button ("🔄 Reset" );
125+ resetButton .addThemeVariants (ButtonVariant .LUMO_PRIMARY );
120126
121127 resetButton .addClickListener (e -> {
122128 resetJourney ();
@@ -144,6 +150,8 @@ private void startJourney() {
144150 "#FF5722" ,
145151 3000 ,
146152 7 ,
153+ "Sari, Iran" ,
154+ "Tehran, Iran" ,
147155 () -> {
148156 // Step 2: Briefcase and passport (1 second)
149157 Notification .show ("Arriving in Tehran - Getting ready to fly..." , 2000 , Notification .Position .BOTTOM_CENTER );
@@ -157,6 +165,8 @@ private void startJourney() {
157165 "#2196F3" ,
158166 4000 ,
159167 5 ,
168+ "Tehran, Iran" ,
169+ "Doha, Qatar" ,
160170 () -> {
161171 // Step 4: Change airplane animation (same position)
162172 Notification .show ("Transit in Doha..." , 2000 , Notification .Position .BOTTOM_CENTER );
@@ -170,6 +180,8 @@ private void startJourney() {
170180 "#2196F3" ,
171181 5000 ,
172182 3 ,
183+ "Doha, Qatar" ,
184+ "Montreal, Canada" ,
173185 () -> {
174186 // Step 6: Paper document (1 second)
175187 Notification .show ("Customs in Montreal..." , 2000 , Notification .Position .BOTTOM_CENTER );
@@ -183,6 +195,8 @@ private void startJourney() {
183195 "#E91E63" ,
184196 4000 ,
185197 6 ,
198+ "Montreal, Canada" ,
199+ "Calgary, Canada" ,
186200 () -> {
187201 // Step 8: House at Calgary
188202 showTransition (CALGARY , HOUSE_ICON , 2000 , () ->
@@ -204,9 +218,14 @@ private void startJourney() {
204218 }
205219
206220 private void animateSegment (JLLatLng start , JLLatLng end , JLIcon icon , String pathColor ,
207- int duration , int zoomLevel , Runnable onComplete ) {
221+ int duration , int zoomLevel , String departureName , String destinationName ,
222+ Runnable onComplete ) {
208223 log .info ("Animating segment from {} to {} with icon {}" , start , end , icon );
209224
225+ // Add popup at departure
226+ JLPopup departurePopup = mapView .getUiLayer ().addPopup (start ,
227+ "<div style='font-weight: bold; color: #FF5722;'>📍 Departure: " + departureName + "</div>" );
228+
210229 // Remove previous path if exists
211230 if (currentPath != null ) {
212231 log .info ("Removing previous path" );
@@ -238,10 +257,23 @@ private void animateSegment(JLLatLng start, JLLatLng end, JLIcon icon, String pa
238257 log .info ("Flying to midpoint: {}" , midPoint );
239258 mapView .getControlLayer ().flyTo (midPoint , zoomLevel );
240259
260+ // Add popup at destination
261+ JLPopup destinationPopup = mapView .getUiLayer ().addPopup (end ,
262+ "<div style='font-weight: bold; color: #4CAF50;'>🎯 Destination: " + destinationName + "</div>" );
263+
241264 // Animate marker along path
242265 log .info ("Starting marker animation" );
243266 UI .getCurrent ().push ();
244- animateMarkerAlongPath (icon , pathPoints , duration , onComplete );
267+ animateMarkerAlongPath (icon , pathPoints , duration , () -> {
268+ // Remove popups after animation
269+ departurePopup .remove ();
270+ destinationPopup .remove ();
271+
272+ // Call the original onComplete callback
273+ if (onComplete != null ) {
274+ onComplete .run ();
275+ }
276+ });
245277 }
246278
247279 private void animateMarkerAlongPath (JLIcon icon , JLLatLng [] path , int duration , Runnable onComplete ) {
@@ -256,10 +288,10 @@ private void animateMarkerAlongPath(JLIcon icon, JLLatLng[] path, int duration,
256288 // Create the marker once at starting position
257289 if (currentMarker == null ) {
258290 currentMarker = mapView .getUiLayer ().addMarker (path [0 ], null , false );
259- setMarkerIconDirect ( currentMarker , icon );
291+ currentMarker . setIcon ( icon );
260292 } else {
261293 currentMarker .setLatLng (path [0 ]);
262- setMarkerIconDirect ( currentMarker , icon );
294+ currentMarker . setIcon ( icon );
263295 }
264296
265297 ScheduledExecutorService executor = Executors .newSingleThreadScheduledExecutor ();
@@ -302,10 +334,10 @@ private void showTransition(JLLatLng position, JLIcon icon, int duration, Runnab
302334 // Just update the marker position and icon, don't remove
303335 if (currentMarker == null ) {
304336 currentMarker = mapView .getUiLayer ().addMarker (position , null , false );
305- setMarkerIconDirect ( currentMarker , icon );
337+ currentMarker . setIcon ( icon );
306338 } else {
307339 currentMarker .setLatLng (position );
308- setMarkerIconDirect ( currentMarker , icon );
340+ currentMarker . setIcon ( icon );
309341 }
310342
311343 ScheduledExecutorService executor = Executors .newSingleThreadScheduledExecutor ();
@@ -359,29 +391,4 @@ private void resetJourney() {
359391 // Reset view to starting position
360392 mapView .getControlLayer ().flyTo (SARI , 4 );
361393 }
362-
363- /**
364- * Helper method to set marker icon using direct JavaScript execution
365- * This bypasses the toString() issue with JLIcon parameter serialization
366- */
367- private void setMarkerIconDirect (JLMarker marker , JLIcon icon ) {
368- String iconScript = String .format ("""
369- var icon = L.icon({
370- iconUrl: '%s',
371- iconSize: [%d, %d],
372- iconAnchor: [%d, %d]
373- });
374- this.%s.setIcon(icon);
375- """ ,
376- icon .getIconUrl (),
377- (int ) icon .getIconSize ().getX (),
378- (int ) icon .getIconSize ().getY (),
379- (int ) icon .getIconAnchor ().getX (),
380- (int ) icon .getIconAnchor ().getY (),
381- marker .getJLId ()
382- );
383-
384- mapView .getElement ().executeJs (iconScript );
385- log .debug ("Set icon for marker {} using direct JS" , marker .getJLId ());
386- }
387394}
0 commit comments