All Implemented Interfaces:
ImageObserver, MenuContainer, Serializable, Accessible

public final class ImagePane extends JPanel
ImagePane is a lightweight container displaying an image that can be zoomed in and out and panned with ease and simplicity, using adaptive rendering for high quality display and satisfactory performance.

All configuration is done via an Observable/Value-based API, allowing reactive UI updates. Image

An image is loaded via the builder or controlled via the image() Value:

 ImagePane pane = ImagePane.builder()
     .image(bufferedImage)
     .build();

 // Or change the image reactively
 pane.image().set(newImage);
 
When an image is set, it is initially painted centered in the component at the largest possible size, fully visible, with its aspect ratio preserved. This is defined as 100% of the image size and its corresponding zoom level is 1.0. Zooming Zooming can be controlled interactively using either the mouse scroll wheel (default) or mouse buttons, or programmatically via the zoom() Value. To change the zoom device:
 ImagePane pane = ImagePane.builder()
     .zoomDevice(ZoomDevice.MOUSE_BUTTON)
     .build();

 // Or change reactively
 pane.zoomDevice().set(ZoomDevice.NONE);
 
When using ZoomDevice.MOUSE_BUTTON, the left mouse button toggles between zooming in and out modes, and the right button zooms by one increment (default 20%). The zoom increment can be controlled:
 pane.zoomIncrement().set(0.3); // 30% increment
 
For programmatic zoom control, set the zoom device to ZoomDevice.NONE and use the zoom() Value:
 pane.zoom().set(2.0); // Zoom to 200%
 
Mouse wheel zooming is always around the point the mouse pointer is currently at, ensuring that the area being zoomed into remains visible. Programmatic zooming via zoom().set() zooms around the center of the pane.

There are no lower or upper zoom level limits. Auto-Resize When auto-resize is enabled, the image automatically re-fits to the pane whenever the pane is resized:

 ImagePane pane = ImagePane.builder()
     .autoResize(true)
     .build();

 // Or toggle reactively
 pane.autoResize().set(true);
 
When auto-resize is enabled, the image will reset to fit the pane dimensions on every resize event, regardless of the current zoom level. This is useful for responsive layouts where you want the image to always fill the available space. Navigation ImagePane does not use scroll bars for navigation, but can optionally display a navigation image in the upper left corner. The navigation image is a small replica of the main image. Clicking on any point of the navigation image displays that part of the image in the pane, centered. The navigation image can be enabled/disabled via the navigable() State:
 ImagePane pane = ImagePane.builder()
     .navigable(true)
     .build();

 // Or toggle reactively
 pane.navigable().set(false);
 
The image can be dragged with the left mouse button when movable() is enabled (default):
 pane.movable().set(false); // Disable dragging
 
For programmatic navigation, use center(). Coordinate Conversion The pane provides coordinate translation between pane and image coordinate spaces via coordinates(). Use this for overlay drawing or when working with mouse events on the image. Rendering ImagePane uses Nearest Neighbor interpolation for image rendering (default in Java). When the scaled image becomes larger than the original image, Bilinear interpolation is applied, but only to the part of the image displayed in the pane. Custom Overlays The pane supports custom overlay painting for drawing annotations, grids, highlights, or any custom graphics on top of the image. See ImagePane.Builder.overlay(BiConsumer) for details.

The origin() Value provides access to the current image origin (top-left corner position in pane coordinates), which can be used to programmatically position the image to make specific regions visible:

 // Move image to show a specific region
 pane.origin().set(new Point(-200, -100));

 // React to origin changes
 pane.origin().addConsumer(origin ->
     System.out.println("Image origin: " + origin));
 
Example Usage
 BufferedImage image = ImageIO.read(new File("photo.jpg"));

 ImagePane imagePane = ImagePane.builder()
     .image(image)
     .zoomDevice(ZoomDevice.MOUSE_WHEEL)
     .autoResize(true)
     .navigable(true)
     .movable(true)
     .build();

 // Coordinate translation
 Point2D.Double imagePoint = pane.coordinates().toImage(mouseEvent.getPoint());

 // Center image on a specific point
 pane.center().onImage(new Point2D.Double(500, 300));

 // Programmatic zoom
 pane.zoom().set(1.5);

 // React to zoom changes
 pane.zoom().addConsumer(zoom ->
     System.out.println("Zoom level: " + zoom));
 

Originally based on http://today.java.net/pub/a/today/2007/03/27/navigable-image-pane.html Included with express permission from the author, 2019.

Author:
Slav Boleslawski, Björn Darri Sigurðsson
See Also:
  • Field Details

  • Method Details

    • image

      public ImagePane.ImageValue image()
      Note that setting the image via this value without specifying the format does not populate the associated byte[] ComponentValue, for that to happen you must use ImagePane.ImageValue.set(BufferedImage, String)
      Returns:
      the ImagePane.ImageValue controlling the image
    • zoomDevice

      public Value<ImagePane.ZoomDevice> zoomDevice()
      Returns:
      the Value controlling the active ImagePane.ZoomDevice
    • autoResize

      public State autoResize()
      Returns the State controlling whether the image automatically re-fits to the pane on resize. When enabled, the image will reset to fit the pane dimensions whenever the pane is resized, regardless of the current zoom level.
      Returns:
      the State controlling the auto-resize behavior
    • movable

      public State movable()
      Returns:
      the State controlling whether the image is movable within the pane
    • zoomIncrement

      public Value<Double> zoomIncrement()
      Returns:
      the Value controlling the zoom increment
    • zoom

      public Value<Double> zoom()
      Returns:
      the Value controlling the current zoom level
    • origin

      public Value<Point> origin()
      Returns the Value controlling the image origin (the position of the image's top-left corner in pane coordinates). This can be used to programmatically position the image within the pane.

      The origin is typically negative when the image is zoomed in and larger than the pane, representing how much of the image is scrolled off the top-left edge of the pane. Example Usage

       // Move image to show a region at image coordinates (500, 300)
       Point2D.Double imagePoint = new Point2D.Double(500, 300);
       Point2D.Double panePoint = pane.toPaneCoordinates(imagePoint);
      
       // Center that point in the pane
       int centerX = pane.getWidth() / 2;
       int centerY = pane.getHeight() / 2;
       pane.origin().set(new Point(
           centerX - (int) panePoint.x,
           centerY - (int) panePoint.y));
      
       // React to origin changes (e.g., when user drags the image)
       pane.origin().addConsumer(origin ->
           updateVisibleRegionIndicator(origin));
       
      Returns:
      the Value controlling the image origin in pane coordinates
    • scale

      public double scale()
      Returns:
      the current scale
    • reset

      public void reset()
      Resets the view so the image is centered and fits the pane
    • coordinates

      public ImagePane.CoordinateTranslator coordinates()
      Returns:
      the coordinate translator
    • center

      public ImagePane.CenterImage center()
      Returns:
      image centerer
    • readImage

      public static BufferedImage readImage(String imagePath) throws IOException
      Reads an image from the given path
      Parameters:
      imagePath - the path, either file or http
      Returns:
      the loaded image
      Throws:
      IOException - in case of an exception
    • builder

      public static ImagePane.Builder builder()
      Returns:
      a new ImagePane.Builder instance
    • paintComponent

      protected void paintComponent(Graphics g)
      Paints the pane and its image at the current zoom level, location, and interpolation method dependent on the image scale.
      Overrides:
      paintComponent in class JComponent
      Parameters:
      g - the Graphics context for painting