# Class ImageViewer

java.lang.Object
com.codename1.ui.Component
com.codename1.components.ImageViewer

All Implemented Interfaces:
  `Animation, Editable, StyleListener`

public class ImageViewer extends Component

ImageViewer allows zooming/panning an image and potentially flicking between multiple images within a list of images.

E.g. the trivial usage works like this:

    Form hi = new Form("ImageViewer", new BorderLayout());
    ImageViewer iv = new ImageViewer(duke);
    hi.add(BorderLayout.CENTER, iv);

You can simulate pinch to zoom on the simulator by dragging the right button away from the top left corner to zoom in and towards the top left corner to zoom out. On Mac touchpads you can drag two fingers to achieve that.

A more elaborate usage includes flicking between multiple images e.g.:

    Form hi = new Form("ImageViewer", new BorderLayout());

    Image red = Image.createImage(100, 100, 0xffff0000);
    Image green = Image.createImage(100, 100, 0xff00ff00);
    Image blue = Image.createImage(100, 100, 0xff0000ff);
    Image gray = Image.createImage(100, 100, 0xffcccccc);

    ImageViewer iv = new ImageViewer(red);
    iv.setImageList(new DefaultListModel<>(red, green, blue, gray));
    hi.add(BorderLayout.CENTER, iv);

Optional navigation affordances can be enabled when using an image list:

    iv.setNavigationArrowsVisible(true);
    iv.setThumbnailsVisible(true);
    iv.setThumbnailBarHeight(6f);

These options can also be configured globally using theme constants:

- `imageviewerNavigationArrowsBool`
- `imageviewerThumbnailsBool`
- `imageviewerThumbnailBarHeightMM`

You can even download image URL's dynamically into the `ImageViewer` thanks to the usage of the `com.codename1.ui.list.ListModel`. E.g. in this model book cover images are downloaded dynamically:

    Form hi = new Form("ImageViewer", new BorderLayout());
    final EncodedImage placeholder = EncodedImage.createFromImage(
            FontImage.createMaterial(FontImage.MATERIAL_SYNC, s).
                    scaled(300, 300), false);

    class ImageList implements ListModel {
        private int selection;
        private String[] imageURLs = {
            "http://awoiaf.westeros.org/images/thumb/9/93/AGameOfThrones.jpg/300px-AGameOfThrones.jpg",
            "http://awoiaf.westeros.org/images/thumb/3/39/AClashOfKings.jpg/300px-AClashOfKings.jpg",
            "http://awoiaf.westeros.org/images/thumb/2/24/AStormOfSwords.jpg/300px-AStormOfSwords.jpg",
            "http://awoiaf.westeros.org/images/thumb/a/a3/AFeastForCrows.jpg/300px-AFeastForCrows.jpg",
            "http://awoiaf.westeros.org/images/7/79/ADanceWithDragons.jpg"
        };
        private Image[] images;
        private EventDispatcher listeners = new EventDispatcher();

        public ImageList() {
            this.images = new EncodedImage[imageURLs.length];
        }

        public Image getItemAt(final int index) {
            if(images[index] == null) {
                images[index] = placeholder;
                Util.downloadUrlToStorageInBackground(imageURLs[index], "list" + index, (e) -> {
                        try {
                            images[index] = EncodedImage.create(Storage.getInstance().createInputStream("list" + index));
                            listeners.fireDataChangeEvent(index, DataChangedListener.CHANGED);
                        } catch(IOException err) {
                            err.printStackTrace();
                        }
                });
            }
            return images[index];
        }

        public int getSize() {
            return imageURLs.length;
        }

        public int getSelectedIndex() {
            return selection;
        }

        public void setSelectedIndex(int index) {
            selection = index;
        }

        public void addDataChangedListener(DataChangedListener l) {
            listeners.addListener(l);
        }

        public void removeDataChangedListener(DataChangedListener l) {
            listeners.removeListener(l);
        }

        public void addSelectionListener(SelectionListener l) {
        }

        public void removeSelectionListener(SelectionListener l) {
        }

        public void addItem(Image item) {
        }

        public void removeItem(int index) {
        }
    };

    ImageList imodel = new ImageList();

    ImageViewer iv = new ImageViewer(imodel.getItemAt(0));
    iv.setImageList(imodel);
    hi.add(BorderLayout.CENTER, iv);

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `static final int`
  `IMAGE_FILL`
  Indicates the initial position of the image in the viewer to FILL the component size.
  `static final int`
  `IMAGE_FIT`
  Indicates the initial position of the image in the viewer to FIT to the component size

  ### Fields inherited from class Component

  `BASELINE, BOTTOM, BRB_CENTER_OFFSET, BRB_CONSTANT_ASCENT, BRB_CONSTANT_DESCENT, BRB_OTHER, CENTER, CROSSHAIR_CURSOR, DEFAULT_CURSOR, DRAG_REGION_IMMEDIATELY_DRAG_X, DRAG_REGION_IMMEDIATELY_DRAG_XY, DRAG_REGION_IMMEDIATELY_DRAG_Y, DRAG_REGION_LIKELY_DRAG_X, DRAG_REGION_LIKELY_DRAG_XY, DRAG_REGION_LIKELY_DRAG_Y, DRAG_REGION_NOT_DRAGGABLE, DRAG_REGION_POSSIBLE_DRAG_X, DRAG_REGION_POSSIBLE_DRAG_XY, DRAG_REGION_POSSIBLE_DRAG_Y, E_RESIZE_CURSOR, HAND_CURSOR, LEFT, MOVE_CURSOR, N_RESIZE_CURSOR, NE_RESIZE_CURSOR, NW_RESIZE_CURSOR, RIGHT, S_RESIZE_CURSOR, SE_RESIZE_CURSOR, SW_RESIZE_CURSOR, TEXT_CURSOR, TOP, W_RESIZE_CURSOR, WAIT_CURSOR`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `ImageViewer()`
  Default constructor
  `ImageViewer(Image i)`
  Initializes the component with an image

- ## Method Summary

  Modifier and Type
  Method
  Description
  `boolean`
  `animate()`
  Allows the animation to reduce "repaint" calls when it returns false.
  `protected Dimension`
  `calcPreferredSize()`
  Calculates the preferred size based on component content.
  `void`
  `deinitialize()`
  Invoked to indicate that the component initialization is being reversed since the component was detached from the container hierarchy.
  `protected void`
  `dragFinished(int x, int y)`
  Callback indicating that the drag has finished either via drop or by releasing the component
  `Image`
  `getCroppedImage(int backgroundColor)`
  Gets the current image cropped using the current pan and zoom state.
  `Image`
  `getCroppedImage(int width, int height, int backgroundColor)`
  Gets the current image cropped using the current pan and zoom state.
  `Image`
  `getImage()`
  Returns the currently showing image
  `ListModel<Image>`
  `getImageList()`
  Returns the list model containing the images in the we can swipe through
  `int`
  `getImageX()`
  Returns the x position of the image viewport which can be useful when it is being panned by the user
  `int`
  `getImageY()`
  Returns the y position of the image viewport which can be useful when it is being panned by the user
  `String[]`
  `getPropertyNames()`
  A component may expose mutable property names for a UI designer to manipulate, this API is designed for usage internally by the GUI builder code
  `String[]`
  `getPropertyTypeNames()`
  This method is here to workaround an XMLVM array type bug where property types aren't identified properly, it returns the names of the types using the following type names: String,int,double,long,byte,short,char,String[],String[][],byte[],Image,Image[],Object[],ListModel,ListCellRenderer
  `Class[]`
  `getPropertyTypes()`
  Matches the property names method (see that method for further details).
  `Object`
  `getPropertyValue(String name)`
  Returns the current value of the property name, this method is used by the GUI builder
  `Image`
  `getSwipePlaceholder()`
  This image is shown briefly during swiping while the full size image is loaded
  `float`
  `getSwipeThreshold()`
  The swipe threshold is a number between 0 and 1 that indicates the threshold after which the swiped image moves to the next image.
  `float`
  `getThumbnailBarHeight()`
  Gets the thumbnail strip height in millimeters.
  `float`
  `getZoom()`
  Manipulate the zoom level of the application
  `void`
  `initComponent()`
  Allows subclasses to bind functionality that relies on fully initialized and "ready for action" component state
  `boolean`
  `isAllowScaleDown()`
  Allows the image to scale down when image initial position is set to fit this is off by default since the UX isn't great
  `boolean`
  `isAnimatedZoom()`
  Indicates if the zoom should bee animated.
  `boolean`
  `isCycleLeft()`
  By default the ImageViewer cycles from the beginning to the end of the list when going to the left, setting this to false prevents this behaviour
  `boolean`
  `isCycleRight()`
  By default the ImageViewer cycles from the end to the beginning of the list when going to the right, setting this to false prevents this behaviour
  `boolean`
  `isEagerLock()`
  Eager locking effectively locks the right/left images as well as the main image, as a result more heap is taken
  `boolean`
  `isNavigationArrowsVisible()`
  Indicates if side navigation arrows should be painted for moving between images.
  `boolean`
  `isThumbnailsVisible()`
  Indicates if thumbnails should be painted in a strip at the bottom for direct image selection.
  `void`
  `keyReleased(int key)`
  If this Component is focused, the key released event will call this method
  `protected void`
  `laidOut()`
  This is a callback method to inform the Component when it's been laidout on the parent Container
  `void`
  `paint(Graphics g)`
  This method paints the Component on the screen, it should be overriden by subclasses to perform custom drawing or invoke the UI API's to let the PLAF perform the rendering.
  `protected void`
  `paintBackground(Graphics g)`
  This method paints the Component background, it should be overriden by subclasses to perform custom background drawing.
  `protected boolean`
  `pinch(float scale)`
  Invoked by subclasses interested in handling pinch to zoom events, if true is returned other drag events will not be broadcast
  `protected void`
  `pinchReleased(int x, int y)`
  To be implemented by subclasses interested in being notified when a pinch zoom has ended (i.e the user has removed one of their fingers, but is still dragging).
  `void`
  `pointerDragged(int x, int y)`
  If this Component is focused, the pointer dragged event will call this method
  `void`
  `pointerPressed(int x, int y)`
  If this Component is focused, the pointer pressed event will call this method
  `void`
  `pointerReleased(int x, int y)`
  If this Component is focused, the pointer released event will call this method
  `protected void`
  `resetFocusable()`
  Restores the state of the focusable flag to its default state
  `void`
  `setAllowScaleDown(boolean allowScaleDown)`
  Allows the image to scale down when image initial position is set to fit this is off by default since the UX isn't great
  `void`
  `setAnimateZoom(boolean animateZoom)`
  Indicates if the zoom should bee animated.
  `void`
  `setCycleLeft(boolean cycleLeft)`
  By default the ImageViewer cycles from the beginning to the end of the list when going to the left, setting this to false prevents this behaviour
  `void`
  `setCycleRight(boolean cycleRight)`
  By default the ImageViewer cycles from the end to the beginning of the list when going to the right, setting this to false prevents this behaviour
  `void`
  `setEagerLock(boolean eagerLock)`
  Eager locking effectively locks the right/left images as well as the main image, as a result more heap is taken
  `final void`
  `setImage(Image image)`
  Sets the currently showing image
  `void`
  `setImageInitialPosition(int imageInitialPosition)`
  Sets the viewer initial image position to fill or to fit.
  `void`
  `setImageList(ListModel<Image> model)`
  By providing this optional list of images you can allows swiping between multiple images
  `void`
  `setImageNoReposition(Image image)`
  Sets the current image without any changes to the panning/scaling
  `void`
  `setNavigationArrowsVisible(boolean navigationArrowsVisible)`
  Enables side navigation arrows (material font icons) for moving between images.
  `String`
  `setPropertyValue(String name, Object value)`
  Sets a new value to the given property, returns an error message if failed and null if successful.
  `void`
  `setSwipePlaceholder(Image swipePlaceholder)`
  This image is shown briefly during swiping while the full size image is loaded
  `void`
  `setSwipeThreshold(float swipeThreshold)`
  The swipe threshold is a number between 0 and 1 that indicates the threshold after which the swiped image moves to the next image.
  `void`
  `setThumbnailBarHeight(float thumbnailBarHeight)`
  Sets the thumbnail strip height in millimeters.
  `void`
  `setThumbnailsVisible(boolean thumbnailsVisible)`
  Enables a bottom thumbnail strip for direct image selection.
  `void`
  `setZoom(float zoom)`
  Manipulate the zoom level of the application
  `void`
  `setZoom(float zoom, float panPositionX, float panPositionY)`
  Manipulate the zoom level of the application
  `protected boolean`
  `shouldBlockSideSwipe()`
  A component that might need side swipe such as the slider could block it from being used for some other purpose when on top of said component.

  ### Methods inherited from class Component

  `addDragFinishedListener, addDragOverListener, addDropListener, addFocusListener, addLongPressListener, addPointerDraggedListener, addPointerPressedListener, addPointerReleasedListener, addPullToRefresh, addScrollListener, addStateChangeListener, announceForAccessibility, bindProperty, blocksSideSwipe, calcScrollSize, cancelRepaints, clearClientProperties, contains, containsOrOwns, createStyleAnimation, deinitializeCustomStyle, dragEnter, dragExit, draggingOver, dragInitiated, drawDraggedImage, drop, fireClicked, focusGained, focusLost, getAbsoluteX, getAbsoluteY, getAccessibilityText, getAllStyles, getAnimationManager, getBaseline, getBaselineResizeBehavior, getBindablePropertyNames, getBindablePropertyTypes, getBorder, getBottomGap, getBoundPropertyValue, getBounds, getBounds, getClientProperty, getCloudBoundProperty, getCloudDestinationProperty, getComponentForm, getComponentState, getCursor, getDefaultDragTransparency, getDirtyRegion, getDisabledStyle, getDraggedx, getDraggedy, getDragImage, getDragRegionStatus, getDragSpeed, getDragTransparency, getEditingDelegate, getGridPosX, getGridPosY, getHeight, getInlineAllStyles, getInlineDisabledStyles, getInlinePressedStyles, getInlineSelectedStyles, getInlineStylesTheme, getInlineUnselectedStyles, getInnerHeight, getInnerPreferredH, getInnerPreferredW, getInnerWidth, getInnerX, getInnerY, getLabelForComponent, getName, getNativeOverlay, getNextFocusDown, getNextFocusLeft, getNextFocusRight, getNextFocusUp, getOuterHeight, getOuterPreferredH, getOuterPreferredW, getOuterWidth, getOuterX, getOuterY, getOwner, getParent, getPreferredH, getPreferredSize, getPreferredSizeStr, getPreferredTabIndex, getPreferredW, getPressedStyle, getSameHeight, getSameWidth, getScrollable, getScrollAnimationSpeed, getScrollDimension, getScrollOpacity, getScrollOpacityChangeSpeed, getScrollX, getScrollY, getSelectCommandText, getSelectedRect, getSelectedStyle, getSideGap, getStyle, getTabIndex, getTensileLength, getTextSelectionSupport, getTooltip, getUIID, getUIManager, getUnselectedStyle, getVisibleBounds, getVisibleBounds, getWidth, getX, getY, growShrink, handlesInput, hasFixedPreferredSize, hasFocus, hideNativeOverlay, initCustomStyle, initDisabledStyle, initLaf, initPressedStyle, initSelectedStyle, initUnselectedStyle, installDefaultPainter, isAlwaysTensile, isBlockLead, isCellRenderer, isChildOf, isDragActivated, isDragAndDropOperation, isDraggable, isDragRegion, isDropTarget, isEditable, isEditing, isEnabled, isFlatten, isFocusable, isGrabsPointerEvents, isHidden, isHidden, isHideInLandscape, isHideInPortrait, isIgnorePointerEvents, isInClippingRegion, isInitialized, isOpaque, isOwnedBy, isPinchBlocksDragAndDrop, isRippleEffect, isRTL, isScrollable, isScrollableX, isScrollableY, isScrollVisible, isSelectableInteraction, isSetCursorSupported, isSmoothScrolling, isSnapToGrid, isStickyDrag, isTactileTouch, isTactileTouch, isTensileDragEnabled, isTraversable, isVisible, keyPressed, keyRepeated, longKeyPress, longPointerPress, onScrollX, onScrollY, onSetFocusable, paintBackgrounds, paintBorder, paintBorderBackground, paintComponent, paintComponent, paintIntersectingComponentsAbove, paintLock, paintLockRelease, paintRippleOverlay, paintScrollbars, paintScrollbarX, paintScrollbarY, paintShadows, paramString, parsePreferredSize, pinch, pointerDragged, pointerHover, pointerHoverPressed, pointerHoverReleased, pointerPressed, pointerReleased, putClientProperty, refreshTheme, refreshTheme, refreshTheme, remove, removeDragFinishedListener, removeDragOverListener, removeDropListener, removeFocusListener, removeLongPressListener, removePointerDraggedListener, removePointerPressedListener, removePointerReleasedListener, removeScrollListener, removeStateChangeListener, repaint, repaint, requestFocus, respondsToPointerEvents, scrollRectToVisible, scrollRectToVisible, setAccessibilityText, setAlwaysTensile, setBlockLead, setBoundPropertyValue, setCellRenderer, setCloudBoundProperty, setCloudDestinationProperty, setComponentState, setCursor, setDefaultDragTransparency, setDirtyRegion, setDisabledStyle, setDraggable, setDragTransparency, setDropTarget, setEditingDelegate, setEnabled, setFlatten, setFocus, setFocusable, setGrabsPointerEvents, setHandlesInput, setHeight, setHidden, setHidden, setHideInLandscape, setHideInPortrait, setIgnorePointerEvents, setInitialized, setInlineAllStyles, setInlineDisabledStyles, setInlinePressedStyles, setInlineSelectedStyles, setInlineStylesTheme, setInlineUnselectedStyles, setIsScrollVisible, setLabelForComponent, setName, setNextFocusDown, setNextFocusLeft, setNextFocusRight, setNextFocusUp, setOpaque, setOwner, setPinchBlocksDragAndDrop, setPreferredH, setPreferredSize, setPreferredSizeStr, setPreferredTabIndex, setPreferredW, setPressedStyle, setRippleEffect, setRTL, setSameHeight, setSameSize, setSameWidth, setScrollAnimationSpeed, setScrollOpacityChangeSpeed, setScrollSize, setScrollVisible, setScrollX, setScrollY, setSelectCommandText, setSelectedStyle, setShouldCalcPreferredSize, setSize, setSmoothScrolling, setSnapToGrid, setTabIndex, setTactileTouch, setTensileDragEnabled, setTensileLength, setTooltip, setTraversable, setUIID, setUIID, setUIIDFinal, setUnselectedStyle, setVisible, setWidth, setX, setY, shouldBlockSideSwipeLeft, shouldBlockSideSwipeRight, shouldRenderComponentSelection, showNativeOverlay, startEditingAsync, stopEditing, stripMarginAndPadding, styleChanged, toImage, toString, unbindProperty, updateNativeOverlay, visibleBoundsContains`

  ### Methods inherited from class Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

- ## Field Details

  - ### IMAGE_FIT

    public static final int IMAGE_FIT
    Indicates the initial position of the image in the viewer to FIT to the component size
    See Also:
      - Constant Field Values

  - ### IMAGE_FILL

    public static final int IMAGE_FILL
    Indicates the initial position of the image in the viewer to FILL the component size. Notice this type might drop edges of the images in order to stretch the image to the full size of the Component.
    See Also:
      - Constant Field Values

- ## Constructor Details

  - ### ImageViewer

    public ImageViewer()
    Default constructor

  - ### ImageViewer

    public ImageViewer(Image i)

    Initializes the component with an image

    ###### Parameters

    - `i`: image to show

- ## Method Details

  - ### resetFocusable

    protected void resetFocusable()
    Restores the state of the focusable flag to its default state
    Overrides:
      `resetFocusable` in class `Component`

  - ### getPropertyNames

    public String[] getPropertyNames()

    A component may expose mutable property names for a UI designer to manipulate, this API is designed for usage internally by the GUI builder code

    ###### Returns

    the property names allowing mutation

    Overrides:
      `getPropertyNames` in class `Component`

  - ### shouldBlockSideSwipe

    protected boolean shouldBlockSideSwipe()
    A component that might need side swipe such as the slider could block it from being used for some other purpose when on top of said component.
    Overrides:
      `shouldBlockSideSwipe` in class `Component`

  - ### getPropertyTypes

    public Class[] getPropertyTypes()

    Matches the property names method (see that method for further details).

    ###### Returns

    the types of the properties

    Overrides:
      `getPropertyTypes` in class `Component`

  - ### getPropertyTypeNames

    public String[] getPropertyTypeNames()

    This method is here to workaround an XMLVM array type bug where property types aren't identified properly, it returns the names of the types using the following type names: String,int,double,long,byte,short,char,String[],String[][],byte[],Image,Image[],Object[],ListModel,ListCellRenderer

    ###### Returns

    Array of type names

    Overrides:
      `getPropertyTypeNames` in class `Component`

  - ### getPropertyValue

    public Object getPropertyValue(String name)

    Returns the current value of the property name, this method is used by the GUI builder

    ###### Parameters

    - `name`: the name of the property

    ###### Returns

    the value of said property

    Overrides:
      `getPropertyValue` in class `Component`

  - ### setPropertyValue

    public String setPropertyValue(String name, Object value)

    Sets a new value to the given property, returns an error message if failed and null if successful. Notice that some builtin properties such as "$designMode" might be sent to components to indicate application state.

    ###### Parameters

    - `name`: the name of the property

    - `value`: new value for the property

    ###### Returns

    error message or null

    Overrides:
      `setPropertyValue` in class `Component`

  - ### initComponent

    public void initComponent()
    Allows subclasses to bind functionality that relies on fully initialized and "ready for action" component state
    Overrides:
      `initComponent` in class `Component`

  - ### getImageX

    public int getImageX()

    Returns the x position of the image viewport which can be useful when it is being panned by the user

    ###### Returns

    x position within the image for the top left corner

  - ### getImageY

    public int getImageY()

    Returns the y position of the image viewport which can be useful when it is being panned by the user

    ###### Returns

    y position within the image for the top left corner

  - ### deinitialize

    public void deinitialize()
    Invoked to indicate that the component initialization is being reversed since the component was detached from the container hierarchy. This allows the component to deregister animators and cleanup after itself. This method is the opposite of the initComponent() method.
    Overrides:
      `deinitialize` in class `Component`

  - ### keyReleased

    public void keyReleased(int key)

    If this Component is focused, the key released event will call this method

    ###### Parameters

    - `keyCode`: the key code value to indicate a physical key.
    Overrides:
      `keyReleased` in class `Component`

  - ### pointerPressed

    public void pointerPressed(int x, int y)

    If this Component is focused, the pointer pressed event will call this method

    ###### Parameters

    - `x`: the pointer x coordinate

    - `y`: the pointer y coordinate

    Overrides:
      `pointerPressed` in class `Component`

  - ### dragFinished

    protected void dragFinished(int x, int y)
    Description copied from class: `Component`

    Callback indicating that the drag has finished either via drop or by releasing the component

    ###### Parameters

    - `x`: the x location

    - `y`: the y location

    Overrides:
      `dragFinished` in class `Component`

  - ### pointerReleased

    public void pointerReleased(int x, int y)

    If this Component is focused, the pointer released event will call this method

    ###### Parameters

    - `x`: the pointer x coordinate

    - `y`: the pointer y coordinate

    Overrides:
      `pointerReleased` in class `Component`

  - ### pinchReleased

    protected void pinchReleased(int x, int y)
    Description copied from class: `Component`

    To be implemented by subclasses interested in being notified when a pinch zoom has ended (i.e the user has removed one of their fingers, but is still dragging).

    ###### Parameters

    - `x`: The x-coordinate of the remaining finger in the drag. (Absolute)

    - `y`: The y-coordinate of the remaining finger in the drag. (Absolute)

    ###### Since

    7.0

    Overrides:
      `pinchReleased` in class `Component`

  - ### pointerDragged

    public void pointerDragged(int x, int y)

    If this Component is focused, the pointer dragged event will call this method

    ###### Parameters

    - `x`: the pointer x coordinate

    - `y`: the pointer y coordinate

    Overrides:
      `pointerDragged` in class `Component`

  - ### laidOut

    protected void laidOut()
    This is a callback method to inform the Component when it's been laidout on the parent Container
    Overrides:
      `laidOut` in class `Component`

  - ### pinch

    protected boolean pinch(float scale)

    Invoked by subclasses interested in handling pinch to zoom events, if true is returned other drag events will not be broadcast

    ###### Parameters

    - `scale`: @param scale the scaling of the pinch operation a number larger than 1 means scaling up and smaller than 1 means scaling down. It is recommended that code would threshold the number (so a change between 1.0 and 1.02 shouldn't necessarily trigger zoom). Notice that this number is relevant to current zoom levels and unaware of them so you should also enforce limits of maximum/minimum zoom levels.

    ###### Returns

    false by default

    Overrides:
      `pinch` in class `Component`

  - ### getCroppedImage

    public Image getCroppedImage(int backgroundColor)

    Gets the current image cropped using the current pan and zoom state. The cropped image dimensions will be the result of cropping the full-sized image with the current pan/zoom state. The aspect ratio will match the aspect ratio of the ImageViewer - not the source image itself.

    ###### Parameters

    - `backgroundColor`: The background color, visible for letterboxing.

    ###### Returns

    The cropped image.

    ###### Since

    7.0

  - ### getCroppedImage

    public Image getCroppedImage(int width, int height, int backgroundColor)

    Gets the current image cropped using the current pan and zoom state.

    ###### Parameters

    - `width`: The width of the cropped image. Use -1 to match aspect ratio of the ImageViewer component. Either height or width must be positive.

    - `height`: The height of the cropped image. Use -1 to match aspect ratio of the ImageViewer component. Either height or width must be positive.

    - `backgroundColor`: Background color to use for letterboxing.

    ###### Returns

    Cropped image in specified dimensions.

    ###### Since

    7.0

  - ### calcPreferredSize

    protected Dimension calcPreferredSize()

    Calculates the preferred size based on component content. This method is invoked lazily by getPreferred size.

    ###### Returns

    the calculated preferred size based on component content

    Overrides:
      `calcPreferredSize` in class `Component`

  - ### animate

    public boolean animate()

    Allows the animation to reduce "repaint" calls when it returns false. It is called once for every frame. Frames are defined by the `com.codename1.ui.Display` class.

    ###### Returns

    true if a repaint is desired or false if no repaint is necessary

    Specified by:
      `animate` in interface `Animation`
    Overrides:
      `animate` in class `Component`

  - ### isAllowScaleDown

    public boolean isAllowScaleDown()

    Allows the image to scale down when image initial position is set to fit this is off by default since the UX isn't great

    ###### Returns

    the allowScaleDown

  - ### setAllowScaleDown

    public void setAllowScaleDown(boolean allowScaleDown)

    Allows the image to scale down when image initial position is set to fit this is off by default since the UX isn't great

    ###### Parameters

    - `allowScaleDown`: the allowScaleDown to set

  - ### paint

    public void paint(Graphics g)

    This method paints the Component on the screen, it should be overriden by subclasses to perform custom drawing or invoke the UI API's to let the PLAF perform the rendering.

    ###### Parameters

    - `g`: the component graphics
    Specified by:
      `paint` in interface `Animation`
    Overrides:
      `paint` in class `Component`

  - ### paintBackground

    protected void paintBackground(Graphics g)

    This method paints the Component background, it should be overriden by subclasses to perform custom background drawing.

    ###### Parameters

    - `g`: the component graphics
    Overrides:
      `paintBackground` in class `Component`

  - ### getImage

    public Image getImage()

    Returns the currently showing image

    ###### Returns

    the image

  - ### setImage

    public final void setImage(Image image)

    Sets the currently showing image

    ###### Parameters

    - `image`: the image to set

  - ### setImageNoReposition

    public void setImageNoReposition(Image image)

    Sets the current image without any changes to the panning/scaling

    ###### Parameters

    - `image`: new image instance

  - ### getImageList

    public ListModel<Image> getImageList()

    Returns the list model containing the images in the we can swipe through

    ###### Returns

    the list model

  - ### setImageList

    public void setImageList(ListModel<Image> model)

    By providing this optional list of images you can allows swiping between multiple images

    ###### Parameters

    - `model`: a list of images

  - ### setAnimateZoom

    public void setAnimateZoom(boolean animateZoom)

    Indicates if the zoom should bee animated. It's true by default

    ###### Parameters

    - `animateZoom`: true if zoom is animated

  - ### isAnimatedZoom

    public boolean isAnimatedZoom()

    Indicates if the zoom should bee animated. It's true by default

    ###### Returns

    true if zoom is animated

  - ### isNavigationArrowsVisible

    public boolean isNavigationArrowsVisible()

    Indicates if side navigation arrows should be painted for moving between images.

    ###### Returns

    `true` if side navigation arrows are visible.

  - ### setNavigationArrowsVisible

    public void setNavigationArrowsVisible(boolean navigationArrowsVisible)

    Enables side navigation arrows (material font icons) for moving between images.

    ###### Parameters

    - `navigationArrowsVisible`: `true` to show side navigation arrows.

  - ### isThumbnailsVisible

    public boolean isThumbnailsVisible()

    Indicates if thumbnails should be painted in a strip at the bottom for direct image selection.

    ###### Returns

    `true` if the thumbnail strip is visible.

  - ### setThumbnailsVisible

    public void setThumbnailsVisible(boolean thumbnailsVisible)

    Enables a bottom thumbnail strip for direct image selection.

    ###### Parameters

    - `thumbnailsVisible`: `true` to show thumbnails.

  - ### getThumbnailBarHeight

    public float getThumbnailBarHeight()

    Gets the thumbnail strip height in millimeters.

    ###### Returns

    Height of the thumbnail strip in millimeters.

  - ### setThumbnailBarHeight

    public void setThumbnailBarHeight(float thumbnailBarHeight)

    Sets the thumbnail strip height in millimeters.

    ###### Parameters

    - `thumbnailBarHeight`: Height of the thumbnail strip in millimeters.

  - ### getZoom

    public float getZoom()

    Manipulate the zoom level of the application

    ###### Returns

    the zoom

  - ### setZoom

    public void setZoom(float zoom)

    Manipulate the zoom level of the application

    ###### Parameters

    - `zoom`: the zoom to set

  - ### setZoom

    public void setZoom(float zoom, float panPositionX, float panPositionY)

    Manipulate the zoom level of the application

    ###### Parameters

    - `zoom`: the zoom to set

    - `panPositionX`: A float value between 0 and 1 to set the image x position

    - `panPositionY`: A float value between 0 and 1 to set the image y position

  - ### getSwipePlaceholder

    public Image getSwipePlaceholder()

    This image is shown briefly during swiping while the full size image is loaded

    ###### Returns

    the swipePlaceholder

  - ### setSwipePlaceholder

    public void setSwipePlaceholder(Image swipePlaceholder)

    This image is shown briefly during swiping while the full size image is loaded

    ###### Parameters

    - `swipePlaceholder`: the swipePlaceholder to set

  - ### isEagerLock

    public boolean isEagerLock()

    Eager locking effectively locks the right/left images as well as the main image, as a result more heap is taken

    ###### Returns

    the eagerLock

  - ### setEagerLock

    public void setEagerLock(boolean eagerLock)

    Eager locking effectively locks the right/left images as well as the main image, as a result more heap is taken

    ###### Parameters

    - `eagerLock`: the eagerLock to set

  - ### isCycleLeft

    public boolean isCycleLeft()

    By default the ImageViewer cycles from the beginning to the end of the list when going to the left, setting this to false prevents this behaviour

    ###### Returns

    true if it should cycle left from beginning

  - ### setCycleLeft

    public void setCycleLeft(boolean cycleLeft)

    By default the ImageViewer cycles from the beginning to the end of the list when going to the left, setting this to false prevents this behaviour

    ###### Parameters

    - `cycleLeft`: the cycle left to set

  - ### isCycleRight

    public boolean isCycleRight()

    By default the ImageViewer cycles from the end to the beginning of the list when going to the right, setting this to false prevents this behaviour

    ###### Returns

    true if it should cycle right from the end

  - ### setCycleRight

    public void setCycleRight(boolean cycleRight)

    By default the ImageViewer cycles from the end to the beginning of the list when going to the right, setting this to false prevents this behaviour

    ###### Parameters

    - `cycleRight`: the cycle right to set

  - ### getSwipeThreshold

    public float getSwipeThreshold()

    The swipe threshold is a number between 0 and 1 that indicates the threshold after which the swiped image moves to the next image. Below that number the image will bounce back

    ###### Returns

    the threshold

  - ### setSwipeThreshold

    public void setSwipeThreshold(float swipeThreshold)

    The swipe threshold is a number between 0 and 1 that indicates the threshold after which the swiped image moves to the next image. Below that number the image will bounce back

    ###### Parameters

    - `swipeThreshold`: the swipeThreshold to set

  - ### setImageInitialPosition

    public void setImageInitialPosition(int imageInitialPosition)

    Sets the viewer initial image position to fill or to fit.

    ###### Parameters

    - `imageInitialPosition`: values can be IMAGE_FILL or IMAGE_FIT