Class ImageView

java.lang.Object
limn.scene.Widget<ImageView>
limn.components.ImageView

public final class ImageView extends Widget<ImageView>
Displays an Image: a full-color picture, or a monochrome/mask icon when a tint is set. A tint recolours an Icon's shape (its alpha becomes the shape, drawn in the tint, so an icon follows the theme); on an Image it multiplies each pixel's colour, so white takes the tint and black stays black. A picture to be recoloured as a shape is given as an icon, BitmapIcon.mask(limn.graphics.Image...). ImageView.Fit controls how the image maps into the widget bounds.

Or an Icon, drawn at the view's own size and density each time either changes: an SVG illustration stays sharp at any size and on any screen. An icon's natural size is an SVG's own, a bitmap icon's largest picture, and 24 points for any other. ImageView.Fit, the tint and dragging behave as for an image, a tintable icon taking the tint as its colour; an animated icon plays here with the controls an animated image has.

A view can let its picture be dragged to another widget or another program (setDragEnabled(boolean)); it does not unless asked, most pictures in a form being decoration.

  • Constructor Details

    • ImageView

      public ImageView(@Nullable Image image)
      Shows an image at its natural size until the layout says otherwise.
    • ImageView

      public ImageView(@Nullable Icon icon)
      Shows an icon at its natural size until the layout says otherwise, drawn at the view's own size and density.
      Parameters:
      icon - the icon, or null for nothing
  • Method Details

    • setIcon

      public ImageView setIcon(@Nullable Icon newIcon)
      Replaces what is shown with an icon, re-measuring if its natural size differs. An animated icon is played from its first frame, unless setPlaying(false) holds it. UI thread only.
      Parameters:
      newIcon - the icon, or null for nothing
      Returns:
      this view
    • icon

      public @Nullable Icon icon()
      Returns:
      the icon shown, or null when the view shows an image or nothing
    • image

      public @Nullable Image image()
      Returns:
      the image shown, or null when the view shows an icon or nothing
    • setImage

      public ImageView setImage(@Nullable Image newImage)
      Replaces the image, re-measuring if its natural size differs. An animated image is played from its first frame, unless setPlaying(false) holds it. UI thread only.
    • setPlaying

      public ImageView setPlaying(boolean play)
      Plays an animated image, or holds the frame shown. A view plays unless told not to: a picture that moves is expected to, and makes no sound. Playing one that has finished starts it again. Nothing happens to a still image, and the setting is kept for the next image the view is given. UI thread only.
    • isPlaying

      public boolean isPlaying()
      Returns:
      whether an animated image is moving now: playing, and not at its end
    • setSpeed

      public ImageView setSpeed(float newSpeed)
      Sets how fast an animated image plays: 1 is the image's own times, 2 twice as fast.
      Throws:
      IllegalArgumentException - if newSpeed is not above 0
    • setLoop

      public ImageView setLoop(ImageAnimation.Loop newLoop)
      Sets how many turns an animated image makes: as many as the image asks for (ImageAnimation.Loop.FILE, unless set), without end, once, a number of times, or forward and back.
    • seekFrame

      public ImageView seekFrame(int frame)
      Shows one frame of an animated image, from the start of its time.
      Throws:
      IndexOutOfBoundsException - if the image has no such frame
    • frameIndex

      public int frameIndex()
      Returns:
      which frame of an animated image is shown, from 0; 0 for a still image
    • onFinished

      public ImageView onFinished(@Nullable Runnable handler)
      Sets what is told when an animated image's last turn ends. One that turns without end never tells.
      Parameters:
      handler - the handler, or null to clear the slot
      Returns:
      this view
      Throws:
      IllegalStateException - if a handler is already registered
    • onDetached

      protected void onDetached()
      Description copied from class: Widget
      Called when this widget leaves the scene: detached from the tree, moved into another scene (told this before the Widget.onAttached() of the scene it joins), or still in it when the scene's window closes, which detaches every widget the scene has. What was taken in Widget.onAttached() from something that outlives the window (a listener's place in a list of the process's, a resource of the system's) is given back here.

      Widget.scene() still answers the scene being left, and becomes null once this returns, so releasing something the scene owns needs no field of your own to remember it by. Fires bottom-up, so children run before their parent, and every one of them can still reach the scene.

      Release resources here, but GPU resources must be handed to Scene.disposeLater(limn.graphics.GpuSurface) (disposal needs the owning GL context, which is only current inside a frame). Not called on Widget.setVisible(boolean). Default no-op.

      Overrides:
      onDetached in class Widget<ImageView>
    • setFit

      public ImageView setFit(ImageView.Fit newFit)
      How the image fills its box when the two aspect ratios differ.
    • setTint

      public ImageView setTint(@Nullable Color newTint)
      Tints what is shown; null draws it in full color. An Icon is recoloured: its shape drawn in the tint. An Image is multiplied by it, pixel by pixel, so a white picture takes the tint and a dark one stays dark; BitmapIcon.mask(limn.graphics.Image...) turns an image into an icon that recolours.
    • setPreferredSize

      public ImageView setPreferredSize(float width, float height)
      Fixed preferred size in logical points (-1 = natural image size).
    • setDragEnabled

      public ImageView setDragEnabled(boolean enabled)
      Lets the user drag the picture out of this view (default off), as DataFormat.IMAGE, for a target to copy: a drop area of this program, an editor, a folder. A target may call what it did a move; the view keeps its picture all the same. What follows the pointer is the picture as the view shows it, with its own transparency, made smaller when the view is large. From the keyboard, the scene's drag key picks it up when the view is focusable. UI thread only.
      Parameters:
      enabled - whether the picture can be dragged
      Returns:
      this view
    • setDragFileName

      public ImageView setDragFileName(@Nullable String name)
      Has a dragged picture offered as a file as well, under this name (default: not). Some targets take a picture only as a file, the desktop and a file manager among them; for those the picture is written as a PNG to the temporary directory when one asks for it, see Transfer.withImageAsFile(java.lang.String). It is not done unless asked, since it writes to disk. UI thread only.
      Parameters:
      name - the file's name, such as "logo.png", or null for no file
      Returns:
      this view
    • setDragWithinWindow

      public ImageView setDragWithinWindow(boolean within)
      Keeps a drag of the picture inside its window (default: not): no other program is offered it, and no other window. UI thread only.
      Parameters:
      within - whether a drag stays in the window it began in
      Returns:
      this view
    • isDragWithinWindow

      public boolean isDragWithinWindow()
      Returns:
      whether a drag of the picture stays in its window
    • isDragEnabled

      public boolean isDragEnabled()
      Returns:
      whether the picture can be dragged
    • onDragStart

      protected @Nullable Drag onDragStart(DragStartEvent event)
      Description copied from class: Widget
      Asked when a drag may begin on this widget: the pointer was pressed here and has moved a few points, or the drag key was pressed while this widget had the focus. The question bubbles from the widget under the pointer, and the first Drag answered starts the drag; the press is then over for the widget that had it. Default: null, which leaves the gesture to the DRAG events it has always been.
      Overrides:
      onDragStart in class Widget<ImageView>
      Parameters:
      event - where the press began, and whether the keyboard asked
      Returns:
      what to drag, or null
    • onMeasure

      protected Size onMeasure(Constraints constraints)
      Description copied from class: Widget
      Reports the size this widget wants within constraints. Called once per layout pass, and the result is cached against the constraints and the resolved axes (size step, layout direction, locale), so it must be a pure function of them and of this widget's own state.

      Resolve the ControlSize and the LayoutDirection once each here and thread them down; never read either in a constructor. The locale needs no threading: it is in scope, and I18n.locale() answers it wherever text is resolved.

      Specified by:
      onMeasure in class Widget<ImageView>
    • onPaint

      protected void onPaint(Canvas canvas)
      Description copied from class: Widget
      Widget's own background/content, in local coordinates.
      Overrides:
      onPaint in class Widget<ImageView>
    • onAccessibility

      protected void onAccessibility(Accessibility a)
      Publishes this view as one Accessible.Role.IMAGE node, always, and declares nothing else about it.

      The role is the whole announcement, and it is what makes the widget describe itself at all. A picture is information by construction — it is the application's, not the toolkit's, and nothing else in the tree carries it — so the class may not answer the paints-and-says- nothing warning with paintsDecoration(), which is the seam for a wash or a rule and would delete every picture in silence. It also fixes a quieter fault: a view an application had already named, or one carrying a tooltip, survived the transparency predicate on the strength of that name and published under the builder's default role, so the very case a picture is named for reached a reader as a group box wearing the picture's name.

      No name is declared, on purpose. The widget holds no I18nString and an Image carries only its size and its pixels, so there is nothing here to derive one from, and a caption sitting beside a picture is never read as its name. All three ways a picture does get one stay the application's and cost this class nothing: a tooltip through the walk's free default, a bound caption, or setAccessibleName. Nothing is formatted, so a damaged frame that changed nothing allocates no memory to say so.

      Striking a picture out is likewise the application's call through setAccessibleIgnored(true) and never this class's, including when it holds no image yet. A class-level ignore is consulted after the application's own name, caption and role have been written, so it would silently overrule all three with no way to appeal — and on a photograph that has not loaded it would make the node appear and vanish as pictures arrive, throwing away the alt text a reader was given and churning structure for a fact nobody asked about.

      The published box is the widget's own and never the ink. ImageView.Fit centres the drawing and lets it letterbox or overflow, so the two genuinely differ; but the box is what hitTest claims, and a node cut down to the drawing would put a magnifier's cursor somewhere the pointer does not agree with, at the price of running the fit arithmetic again on every publish.

      Overrides:
      onAccessibility in class Widget<ImageView>
      Parameters:
      a - the node being described; write into it, and never keep it