मुख्य सामग्री पर जाएँ
CrossFly 100% ओपन सोर्सGitHub पर फ़ॉलो करें
CrossFlyCrossFly
शुरू करें
सभी उदाहरण
रेसिपीडिवाइस124 पंक्तियाँ · 1 फ़ाइलें

A map with pins

OSM needs no API key, so a map works the moment you write it. Opens in a window of its own — a native view inside a scrolling page floats over everything around it.

यह क्या दिखाता है

A real map with pins on it, and the two things that make a map different from every other widget.

It is a native view on top of the GL canvas, not a component inside it. It does not scroll with a parent, does not clip to one, and does not take part in a screen transition — a fade over a map shows a black rectangle for the whole animation. So a map gets a rectangle of its own and every control you want over it goes outside that rectangle, in ordinary components.

The engine is a constructor argument. Changing provider means building a new MapContainer — there is no setter, and there should not be one. OSM needs no key and is the right default for anything that is not shipping; GOOGLE needs MapContainer.googleMapsKey set before the container is built.

Opened on a button rather than built into this screen, on purpose: a native view inside a scrolling recipe list would float over the recipes above and below it.

अपनी मशीन पर चलाएँ

हर उदाहरण एक साधारण Window है, इसलिए लॉन्चर को सिर्फ़ उसका नाम चाहिए।

gradlew lwjgl3:run --args="classname dev.cf.recipe.R25Map"
इसे बदलना

Java पहले से संकलित होता है, इसलिए ब्राउज़र आपके बदलाव को खुद दोबारा नहीं बना सकता — यहाँ दिखा कोड प्रकाशित होने से पहले TeaVM द्वारा JavaScript में बदला गया था। फ़ाइल को किसी प्रोजेक्ट में कॉपी कीजिए और वह चारों प्लेटफ़ॉर्म पर बिना बदलाव चलती है; ऊपर दी गई कमांड ही पूरी तैयारी है।

यहीं चल रहा हैCrossFly 0.1.32
ऐप शुरू हो रहा है…

TeaVM ने इसे JavaScript में संकलित किया — यह वही कोड है, उसका वीडियो नहीं। · सभी उदाहरण

यह क्या इस्तेमाल करता है

इस उदाहरण में छुए गए फ़्रेमवर्क टाइप। जिनमें लिंक है उनका संदर्भ पृष्ठ मौजूद है।

ButtonComponentDebugGapGridLayoutLatLonMapMapContainerMapPinMaterialIconStylesVerticalLayoutWidgetsWindow

सोर्स कोड

पूरा, बिना कटौती के। यह वही फ़ाइल है, उसका अंश नहीं।

कच्चा
dev/cf/recipe/R25Map.java
package dev.cf.recipe;

import dev.cf.Tones;

import dev.crossfly.map.*;
import dev.crossfly.ui.*;
import dev.crossfly.ui.color.*;
import dev.crossfly.ui.graphics.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.style.*;
import java.util.ArrayList;
import java.util.List;

import static dev.crossfly.ui.Widgets.*;

/**
 * A real map with pins on it, and the two things that make a map different from every other widget.
 *
 * <p><b>It is a native view on top of the GL canvas</b>, not a component inside it. It does not
 * scroll with a parent, does not clip to one, and does not take part in a screen transition — a
 * fade over a map shows a black rectangle for the whole animation. So a map gets a rectangle of its
 * own and every control you want over it goes <i>outside</i> that rectangle, in ordinary
 * components.</p>
 *
 * <p><b>The engine is a constructor argument.</b> Changing provider means building a new
 * {@link MapContainer} — there is no setter, and there should not be one. {@code OSM} needs no key
 * and is the right default for anything that is not shipping; {@code GOOGLE} needs
 * {@code MapContainer.googleMapsKey} set before the container is built.</p>
 *
 * <p>Opened on a button rather than built into this screen, on purpose: a native view inside a
 * scrolling recipe list would float over the recipes above and below it.</p>
 */
public class R25Map extends Recipe
{
   /** A few coordinates to plot. Real ones come from your store — with the nulls filtered out. */
   private static final double[][] WHERE = { { 53.7996, -1.5491 }, { 51.2194, 4.4025 },
      { 41.1579, -8.6291 }, { 45.0703, 7.6869 }, { 55.6050, 13.0038 }, { 51.4545, -2.5879 } };
   private static final String[] WHO = { "Northgate", "Bellamy", "Kestrel", "Halden & Roe",
      "Ironvale", "Meridian" };

   public String title()
   {
      return "A map with pins";
   }

   public String note()
   {
      return "OSM needs no API key, so a map works the moment you write it. Opens in a window of"
         + " its own — a native view inside a scrolling page floats over everything around it.";
   }

   public void build(Component body) throws Exception
   {
      body.add(LAY_AUTO, outgap(label("Six suppliers, plotted from coordinates. The pins are data;"
         + " the map only draws them.", 1f, false, Styles.captionColor, Position.START), 0, 0, 0,
         1f));

      Button open = Tones.action("Open the map");
      open.testTag("map.open");
      open.onAction(c -> new MapScreen().show());
      body.add(LAY_AUTO, open);
   }

   /** The map, in a window of its own, with the app's chrome kept outside its rectangle. */
   private static class MapScreen extends Window
   {
      private MapContainer container;

      @Override
      public void onAdd(boolean firstTime) throws Exception
      {
         if (!firstTime)
            return;
         fullscreenColor = Styles.backColor.color();
         setLayout(new VerticalLayout(Position.START, Position.START));

         Component bar = new Component();
         bar.setLayout(new GridLayout(Position.START, Position.CENTER));
         bar.getStyle()
            .ingap(Gap.ofFont(.6f, .5f, .6f, .5f));
         Button back = new Button(MaterialIcon.of(0xE5C4, 1.4f));
         back.onAction(c -> hide());
         bar.add(0f, 1f, back, outgap(label("Suppliers", 1.5f, true, Styles.textColor,
            Position.START), .6f, 0, 0, 0));
         add(0f, bar);

         // OSM: no key, no account, works offline against its own tiles cache. The callback fires
         // when the native view is ready — plotting before that plots into nothing.
         container = new MapContainer(Map.MapEngine.OSM, 0, this::plot);
         add(LAY_FILL, container);
      }

      private void plot()
      {
         try
         {
            final List<MapPin> pins = new ArrayList<>();
            double lat = 0, lon = 0;
            for (int i = 0; i < WHERE.length; i++)
            {
               pins.add(new MapPin().position(WHERE[i][0], WHERE[i][1])
                  .title(WHO[i])
                  .snippet("Supplier"));
               lat += WHERE[i][0];
               lon += WHERE[i][1];
            }

            // batch(): every add is a call across to the native view, and six of them is six
            // round-trips and six redraws. Inside a batch it is one. At six pins nobody notices;
            // at six hundred it is the difference between a map and a freeze.
            container.map.batch(() -> container.map.add(pins.toArray(new MapPin[0])));

            // Open on the middle of what was plotted, not on a fixed point: a map that opens
            // somewhere the data is not makes the user pan before it tells them anything.
            container.map.centerOnLocation(new LatLon(lat / WHERE.length, lon / WHERE.length), 4);
         }
         catch (Exception e)
         {
            dev.crossfly.util.Debug.handle(e);
         }
      }
   }
}
एआई सहायक के लिए

इस पृष्ठ के मशीन-पठनीय रूप, ताकि मॉडल API का अनुमान लगाने के बजाय उदाहरण पढ़ सके।

यह उदाहरण, JSON मेंयह उदाहरण, Markdown में
पिछलाFloating action buttonअगलाImages