Changeset 18604 in josm for trunk/src/org


Ignore:
Timestamp:
2022-11-23T19:12:12+01:00 (2 years ago)
Author:
taylor.smock
Message:

Fix #22519: NPE in Equirectangular#getRotation

This is due to cameraPlane being null initially, and only being updated once
the parent component changes size.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/layer/geoimage/viewers/projections/Equirectangular.java

    r18398 r18604  
    1313import java.util.Set;
    1414
     15import javax.annotation.Nonnull;
     16import javax.annotation.Nullable;
     17
    1518import org.openstreetmap.josm.data.imagery.street_level.Projections;
    1619import org.openstreetmap.josm.gui.layer.geoimage.ImageDisplay;
     
    2528 */
    2629public class Equirectangular extends ComponentAdapter implements IImageViewer {
     30    @Nullable
    2731    private volatile CameraPlane cameraPlane;
    2832    private volatile BufferedImage offscreenImage;
     
    3842        final BufferedImage currentOffscreenImage;
    3943        synchronized (this) {
    40             currentCameraPlane = this.cameraPlane;
     44            final CameraPlane currentPlane = this.cameraPlane;
     45            currentCameraPlane = currentPlane != null ? currentPlane : this.updateCameraPlane(target.width, target.height);
    4146            currentOffscreenImage = this.offscreenImage;
    4247        }
     
    5762    @Override
    5863    public Vector3D getRotation() {
    59         return this.cameraPlane.getRotation();
     64        final CameraPlane currentPlane = this.cameraPlane;
     65        if (currentPlane != null) {
     66            return currentPlane.getRotation();
     67        }
     68        return IImageViewer.super.getRotation();
    6069    }
    6170
     
    6574        if (e.getComponent().getWidth() > 0
    6675                && e.getComponent().getHeight() > 0) {
    67             // FIXME: Do something so that the types of the images are the same between the offscreenImage and
    68             // the image entry
    69             final CameraPlane currentCameraPlane;
    70             synchronized (this) {
    71                 currentCameraPlane = this.cameraPlane;
    72             }
    73             final BufferedImage temporaryOffscreenImage = new BufferedImage(imgDisplay.getWidth(), imgDisplay.getHeight(),
    74                     BufferedImage.TYPE_4BYTE_ABGR);
    75 
    76             Vector3D currentRotation = null;
    77             if (currentCameraPlane != null) {
    78                 currentRotation = currentCameraPlane.getRotation();
    79             }
    80             final CameraPlane temporaryCameraPlane = new CameraPlane(imgDisplay.getWidth(), imgDisplay.getHeight());
    81             if (currentRotation != null) {
    82                 temporaryCameraPlane.setRotation(currentRotation);
    83             }
    84             synchronized (this) {
    85                 this.cameraPlane = temporaryCameraPlane;
    86                 this.offscreenImage = temporaryOffscreenImage;
    87             }
     76            updateCameraPlane(imgDisplay.getWidth(), imgDisplay.getHeight());
    8877            if (imgDisplay instanceof ImageDisplay) {
    8978                ((ImageDisplay) imgDisplay).updateVisibleRectangle();
     
    9382    }
    9483
     84    /**
     85     * Update the current camera plane
     86     * @param width The width to use
     87     * @param height The height to use
     88     */
     89    @Nonnull
     90    private CameraPlane updateCameraPlane(int width, int height) {
     91        // FIXME: Do something so that the types of the images are the same between the offscreenImage and
     92        // the image entry
     93        final CameraPlane currentCameraPlane;
     94        synchronized (this) {
     95            currentCameraPlane = this.cameraPlane;
     96        }
     97        final BufferedImage temporaryOffscreenImage = new BufferedImage(width, height,
     98                BufferedImage.TYPE_4BYTE_ABGR);
     99
     100        Vector3D currentRotation = null;
     101        if (currentCameraPlane != null) {
     102            currentRotation = currentCameraPlane.getRotation();
     103        }
     104        final CameraPlane temporaryCameraPlane = new CameraPlane(width, height);
     105        if (currentRotation != null) {
     106            temporaryCameraPlane.setRotation(currentRotation);
     107        }
     108        synchronized (this) {
     109            this.cameraPlane = temporaryCameraPlane;
     110            this.offscreenImage = temporaryOffscreenImage;
     111        }
     112        return temporaryCameraPlane;
     113    }
     114
    95115    @Override
    96116    public void mouseDragged(final Point from, final Point to, ImageDisplay.VisRect currentVisibleRect) {
    97         if (from != null && to != null) {
    98             this.cameraPlane.setRotationFromDelta(from, to);
     117        final CameraPlane currentPlane = this.cameraPlane;
     118        if (from != null && to != null && currentPlane != null) {
     119            currentPlane.setRotationFromDelta(from, to);
    99120        }
    100121    }
Note: See TracChangeset for help on using the changeset viewer.