Pular para o conteúdo
CrossFly é 100% open sourceSiga no GitHub
CrossFlyCrossFly
Começar

Como deixar o usuário escolher um local no mapa

Propósito. Abrir uma tela de mapa (Google) com pino arrastável e rastreamento GPS, para o usuário confirmar uma posição. O resultado é um LatLon entregue por callback.

APIs usadas

  • LocationPicker(RunnableWith<LatLon> onCapture, double minPdop, boolean canDragPin, boolean highPrecision, boolean streetview) — construtor completo (é a assinatura real da fonte).
    • onCapture — callback chamado com o LatLon confirmado (pode ser null).
    • minPdop — PDOP mínimo aceitável; o botão de confirmar fica oculto até o fix atingir essa precisão (no desktop é sempre liberado).
    • canDragPin — true para permitir arrastar o pino a uma posição customizada.
    • highPrecision — true para GPS de alta precisão.
    • streetview — true para habilitar street view no mapa.
  • LatLon getAnswer() — posição confirmada, ou null se cancelado.
  • Estáticos configuráveis: LocationPicker.defaultZoom, Instrucoes, GpsLocation, CustomLocation, Precision, Meters.

Divergência vs. a descrição do pedido. O LocationPicker não usa show(onAnswer) para o resultado: a coordenada chega pelo RunnableWith<LatLon> onCapture passado no construtor (e também fica em getAnswer()). O onCapture só é chamado quando o usuário confirma com uma posição não-nula. Internamente o picker roda seu próprio GPSThread (classe interna) e já despacha as atualizações via Component.onUI(...), então seu callback executa na paint thread.

Exemplo completo (copiar, colar e rodar)

package com.exemplo;

import dev.crossfly.ui.*;                   // Window, Button, Label
import dev.crossfly.ui.layout.*;            // VerticalLayout
import dev.crossfly.ui.picker.*;            // LocationPicker
import dev.crossfly.map.*;                  // LatLon
import dev.crossfly.util.*;                 // RunnableWith

/** Tela principal executável. Aponte o launcher (classname) e rode: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      Label resultado = new Label("");
      add(LAY_AUTO, resultado);

      Button acao = new Button("Escolher no mapa");
      acao.onAction(c ->
      {
         RunnableWith<LatLon> aoConfirmar = coord ->
         {
            // Já chega na paint thread (o picker usa Component.onUI internamente)
            resultado.setText("Lat " + coord.lat + " / Lon " + coord.lon);
         };

         LocationPicker picker = new LocationPicker(
            aoConfirmar,   // callback com o LatLon confirmado
            30.0,          // minPdop: libera confirmar quando a precisão <= 30m
            true,          // canDragPin: usuário pode arrastar o pino
            true,          // highPrecision
            false);        // streetview
         picker.show();
      });
      add(LAY_AUTO, acao);
   }
}

O trecho abaixo mostra só o miolo. Para rodar, coloque-o no esqueleto MainWindow acima.

Trecho mínimo

// verificado na fonte: LocationPicker.java (constructor linhas 129-141, onCapture/closeWith, getAnswer)
import dev.crossfly.ui.picker.*;           // LocationPicker
import dev.crossfly.map.*;                 // LatLon
import dev.crossfly.util.*;                // RunnableWith

RunnableWith<LatLon> aoConfirmar = coord -> {
   // Já chega na paint thread (o picker usa Component.onUI internamente)
   double lat = coord.lat, lon = coord.lon;
   salvarLocal(lat, lon);
};

LocationPicker picker = new LocationPicker(
   aoConfirmar,   // callback com o LatLon confirmado
   30.0,          // minPdop: libera confirmar quando a precisão <= 30m
   true,          // canDragPin: usuário pode arrastar o pino
   true,          // highPrecision
   false);        // streetview
picker.show();

// Alternativa: ler o resultado depois via getAnswer() (null se cancelado)

Aprofunde-se

Esta página foi útil?