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

Images

Decode once, keep the Image, reuse it. Loading inside onPaint or inside a list's bind step is what makes scrolling stutter where the pictures are.

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

Images, and the two questions that come up before the picture does.

How does it fill its box? ImageSize is the whole answer, and picking wrong is the most visible mistake in an app: a portrait photo stretched into a landscape tile is noticed by everybody and reported by nobody, because it looks like a bad photo rather than a bug. Cropping to fill is almost always right for a photo; fitting inside is almost always right for a logo.

Where does the image come from? An app's own assets, or bytes it was handed — a camera capture, a database blob, a download. Both end up as an Image, and neither belongs in onPaint: decoding is expensive, and doing it per frame is the classic reason a list stutters exactly where the pictures are.

Drawn here rather than loaded from a file, so the recipe carries no asset of its own — but a generated image and a decoded one behave identically from this point on.

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

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

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

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

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

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

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

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

CardColorUtilsComponentGapImageImageViewRelativeStylesWidgets

सोर्स कोड

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

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

import dev.crossfly.ui.*;
import dev.crossfly.ui.color.ColorUtils;
import dev.crossfly.ui.graphics.*;
import dev.crossfly.ui.image.Image;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.style.*;

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

/**
 * Images, and the two questions that come up before the picture does.
 *
 * <p><b>How does it fill its box?</b> {@link ImageView.ImageSize} is the whole answer, and picking
 * wrong is the most visible mistake in an app: a portrait photo stretched into a landscape tile is
 * noticed by everybody and reported by nobody, because it looks like a bad photo rather than a bug.
 * Cropping to fill is almost always right for a photo; fitting inside is almost always right for a
 * logo.</p>
 *
 * <p><b>Where does the image come from?</b> An app's own assets, or bytes it was handed — a camera
 * capture, a database blob, a download. Both end up as an {@link Image}, and neither belongs in
 * {@code onPaint}: decoding is expensive, and doing it per frame is the classic reason a list
 * stutters exactly where the pictures are.</p>
 *
 * <p>Drawn here rather than loaded from a file, so the recipe carries no asset of its own — but a
 * generated image and a decoded one behave identically from this point on.</p>
 */
public class R26Images extends Recipe
{
   public String title()
   {
      return "Images";
   }

   public String note()
   {
      return "Decode once, keep the Image, reuse it. Loading inside onPaint or inside a list's bind"
         + " step is what makes scrolling stutter where the pictures are.";
   }

   public void build(Component body) throws Exception
   {
      // Made once, held, reused by all three views below — the point of the recipe.
      Image swatch = gradient(240, 160);

      // The names repay one careful reading, because two of them are the opposite of what they
      // sound like. RATIO fits the whole picture INSIDE the box; FIT scales until it COVERS the
      // box and crops what hangs over. Guessing between those two is how a portrait photo ends up
      // letterboxed in a tile that had room to crop it properly.
      show(body, "RATIO — the whole picture, inside the box", swatch, ImageSize.RATIO);
      show(body, "FIT — covers the box, crops the overflow", swatch, ImageSize.FIT);
      show(body, "STRETCH — fills by distorting. Almost never right", swatch, ImageSize.STRETCH);
   }

   private void show(Component body, String caption, Image img, ImageSize size)
      throws Exception
   {
      Card c = new Card();
      c.add(LAY_AUTO, label(caption, 1f, true, Styles.textColor, Position.START));
      ImageView v = new ImageView(img, size);
      v.getStyle()
         .autoHeight(Relative.ofFont(6f));
      c.add(LAY_AUTO, outgap(v, 0, .4f, 0, 0));
      c.getStyle()
         .outgap(Gap.ofFont(0, 0, 0, .6f));
      body.add(LAY_AUTO, c);
   }

   /**
    * Builds an image in memory from the theme's own colours.
    *
    * <p>An {@code Image} is pixels; where they came from stops mattering the moment you have one.
    * The same object could have arrived from {@code PhotoPicker}, from a SQLite blob or from a
    * download, and every line after this one would be unchanged.</p>
    */
   private static Image gradient(int w, int h) throws Exception
   {
      Image img = Image.createSurface(w, h);
      int[] px = new int[w * h];
      int from = Styles.primaryColor.color(), to = tertiary().color();
      for (int y = 0; y < h; y++)
      {
         int rowColor = ColorUtils.lerpColor(from, to, y / (float) h);
         for (int x = 0; x < w; x++)
            // Diagonal bands, so cropping and stretching are both obvious at a glance.
            px[y * w + x] = ((x + y) / 18) % 2 == 0 ? rowColor
               : ColorUtils.lerpColor(rowColor, Styles.backColor.color(), .35f);
      }
      img.setPixels(px);
      // Pixels written, texture stale: applyChanges is what pushes them to the GPU. Forgetting it
      // gives you an image that is correct in memory and blank on screen.
      img.applyChanges();
      return img;
   }
}
एआई सहायक के लिए

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

यह उदाहरण, JSON मेंयह उदाहरण, Markdown में
पिछलाA map with pinsअगलाKeyboard and focus