This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit d6ca8baa263ac788e4d140502099af3977b7a7b4
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Wed Feb 10 15:41:54 2021 +0100

    Better catching of exceptions to be reported to user.
---
 .../apache/sis/gui/coverage/CoverageCanvas.java    | 41 ++++++++++------------
 .../org/apache/sis/gui/coverage/RenderingData.java |  8 ++---
 .../apache/sis/gui/coverage/CoverageCanvasApp.java | 27 ++------------
 3 files changed, 24 insertions(+), 52 deletions(-)

diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageCanvas.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageCanvas.java
index ff1a09e..389ef6d 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageCanvas.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageCanvas.java
@@ -62,7 +62,6 @@ import 
org.apache.sis.referencing.operation.transform.MathTransforms;
 import org.apache.sis.geometry.Envelope2D;
 import org.apache.sis.geometry.Shapes2D;
 import org.apache.sis.image.PlanarImage;
-import org.apache.sis.image.ErrorHandler;
 import org.apache.sis.image.Interpolation;
 import org.apache.sis.coverage.Category;
 import org.apache.sis.gui.map.MapCanvas;
@@ -183,6 +182,15 @@ public class CoverageCanvas extends MapCanvasAWT {
     StatusBar statusBar;
 
     /**
+     * If errors occurred during tile computations, details about the error. 
Otherwise {@code null}.
+     * This field is set once by some background thread if one or more errors 
occurred during calls
+     * to {@link RenderedImage#getTile(int, int)}. In such case, we store 
information about the error
+     * and let the rendering process continue with a tile placeholder (by 
default a cross (X) in a box).
+     * This field is read in JavaFX thread for transferring the error 
description to {@link #errorProperty()}.
+     */
+    private volatile LogRecord errorReport;
+
+    /**
      * The resource from which the data has been read, or {@code null} if 
unknown.
      * This is used only for determining a target window for logging records.
      *
@@ -212,7 +220,7 @@ public class CoverageCanvas extends MapCanvasAWT {
      */
     CoverageCanvas(final Locale locale) {
         super(locale);
-        data                  = new RenderingData();
+        data                  = new RenderingData((report) -> errorReport = 
report.getDescription());
         derivedImages         = new EnumMap<>(Stretching.class);
         coverageProperty      = new SimpleObjectProperty<>(this, "coverage");
         sliceExtentProperty   = new SimpleObjectProperty<>(this, 
"sliceExtent");
@@ -528,7 +536,7 @@ public class CoverageCanvas extends MapCanvasAWT {
      *   <li>Paint the image.</li>
      * </ol>
      */
-    private static final class Worker extends Renderer implements ErrorHandler 
{
+    private static final class Worker extends Renderer {
         /**
          * Value of {@link CoverageCanvas#data} at the time this worker has 
been initialized.
          */
@@ -611,11 +619,6 @@ public class CoverageCanvas extends MapCanvasAWT {
         private IsolineRenderer.Snapshot[] isolines;
 
         /**
-         * If errors occurred during tile computations, details about the 
error. Otherwise {@code null}.
-         */
-        private LogRecord errorReport;
-
-        /**
          * Creates a new renderer. Shall be invoked in JavaFX thread.
          */
         Worker(final CoverageCanvas canvas) {
@@ -732,7 +735,7 @@ public class CoverageCanvas extends MapCanvasAWT {
             if (prefetchedImage instanceof TileErrorHandler.Executor) {
                 ((TileErrorHandler.Executor) prefetchedImage).execute(
                         () -> gr.drawRenderedImage(prefetchedImage, 
resampledToDisplay),
-                        new TileErrorHandler(this, CoverageCanvas.class, 
"paint"));
+                        new TileErrorHandler(data.processor.getErrorHandler(), 
CoverageCanvas.class, "paint"));
             } else {
                 gr.drawRenderedImage(prefetchedImage, resampledToDisplay);
             }
@@ -751,16 +754,6 @@ public class CoverageCanvas extends MapCanvasAWT {
         }
 
         /**
-         * Invoked if an error occurred during a call to {@link 
RenderedImage#getTile(int, int)}.
-         * This method stores information about the error and let the 
rendering process continue
-         * with a tile placeholder (by default a cross (X) in a box).
-         */
-        @Override
-        public void handle(final Report details) {
-            errorReport = details.getDescription();
-        }
-
-        /**
          * Invoked in JavaFX thread after successful {@link 
#paint(Graphics2D)} completion.
          * This method stores the computation results.
          */
@@ -781,7 +774,7 @@ public class CoverageCanvas extends MapCanvasAWT {
      * If the resampled image changed, all previously cached images are 
discarded.
      */
     private void cacheRenderingData(final Worker worker) {
-        if (TRACE && data.changed(worker.data)) {
+        if (TRACE && data.hasChanged(worker.data)) {
             trace("cacheRenderingData(…): new visual coverage:%n%s", 
worker.data);
         }
         data = worker.data;
@@ -822,10 +815,12 @@ public class CoverageCanvas extends MapCanvasAWT {
         }
         /*
          * If error(s) occurred during calls to `RenderedImage.getTile(tx, 
ty)`, reports those errors.
+         * The `errorReport` field is reset to `null` in preparation for the 
next rendering operation.
          */
-        final LogRecord errorReport = worker.errorReport;
-        if (errorReport != null) {
-            errorOccurred(errorReport.getThrown());
+        final LogRecord report = errorReport;
+        if (report != null) {
+            errorReport = null;
+            errorOccurred(report.getThrown());
         }
     }
 
diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/RenderingData.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/RenderingData.java
index 2ba2b33..9d7b3c3 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/RenderingData.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/RenderingData.java
@@ -202,12 +202,12 @@ final class RenderingData implements Cloneable {
     /**
      * Creates a new instance initialized to no image.
      *
-     * @todo Listen to logging messages. We need to create a logging panel 
first.
+     * @param  errorHandler  where to report errors during tile computations.
      */
-    RenderingData() {
+    RenderingData(final ErrorHandler errorHandler) {
         selectedDerivative = Stretching.NONE;
         processor = new ImageProcessor();
-        processor.setErrorHandler(ErrorHandler.LOG);
+        processor.setErrorHandler(errorHandler);
         processor.setImageResizingPolicy(ImageProcessor.Resizing.EXPAND);
     }
 
@@ -543,7 +543,7 @@ final class RenderingData implements Cloneable {
      * Returns whether {@link #dataGeometry} or {@link #objectiveToCenter} 
changed since a previous rendering.
      * This is used for information purposes only.
      */
-    final boolean changed(final RenderingData previous) {
+    final boolean hasChanged(final RenderingData previous) {
         /*
          * Really !=, not Object.equals(Object), because we rely on new 
instances to be created
          * (even if equal) as a way to detect that cached values have not been 
reused.
diff --git 
a/application/sis-javafx/src/test/java/org/apache/sis/gui/coverage/CoverageCanvasApp.java
 
b/application/sis-javafx/src/test/java/org/apache/sis/gui/coverage/CoverageCanvasApp.java
index bcba2d9..ce23aaa 100644
--- 
a/application/sis-javafx/src/test/java/org/apache/sis/gui/coverage/CoverageCanvasApp.java
+++ 
b/application/sis-javafx/src/test/java/org/apache/sis/gui/coverage/CoverageCanvasApp.java
@@ -20,8 +20,6 @@ import java.util.Random;
 import java.awt.Point;
 import java.awt.image.DataBuffer;
 import javafx.application.Application;
-import javafx.beans.value.ChangeListener;
-import javafx.beans.value.ObservableValue;
 import javafx.scene.layout.BorderPane;
 import javafx.scene.Scene;
 import javafx.stage.Stage;
@@ -46,7 +44,7 @@ import 
org.apache.sis.referencing.operation.transform.MathTransforms;
  * @since   1.1
  * @module
  */
-public class CoverageCanvasApp extends Application implements 
ChangeListener<Throwable> {
+public class CoverageCanvasApp extends Application {
     /**
      * Size of the artificial tiles. Should be small enough so we can have 
many of them.
      * Width and height should be different in order to increase the chance to 
see bugs
@@ -72,7 +70,6 @@ public class CoverageCanvasApp extends Application implements 
ChangeListener<Thr
     @Override
     public void start(final Stage window) {
         final CoverageCanvas canvas = new CoverageCanvas();
-        canvas.errorProperty().addListener(this);
         final StatusBar statusBar = new StatusBar(null, canvas);
         canvas.statusBar = statusBar;
         canvas.setCoverage(createImage());
@@ -101,12 +98,7 @@ public class CoverageCanvasApp extends Application 
implements ChangeListener<Thr
      * have artificial errors in order to see the error controls.
      */
     private static GridCoverage2D createImage() {
-        /*
-         * A few interresting seeds for debugging:
-         * -638852012230008460L, 987724905110811687L,
-         * 4120510106559901474L, 4533692522112080642L, 2518316107261433588L
-         */
-        final Random random = new Random(987724905110811687L);
+        final Random random = new Random();
         final int width  = TILE_WIDTH  * 4;
         final int height = TILE_HEIGHT * 2;
         final TiledImageMock image = new TiledImageMock(
@@ -134,19 +126,4 @@ public class CoverageCanvasApp extends Application 
implements ChangeListener<Thr
         return new GridCoverage2D(new GridGeometry(null, 
PixelInCell.CELL_CORNER,
                 MathTransforms.identity(2), 
CommonCRS.Engineering.DISPLAY.crs()), null, image);
     }
-
-    /**
-     * Invoked when an exception occurred during rendering.
-     *
-     * @param  property  the {@link CoverageCanvas#errorProperty()}.
-     * @param  oldValue  the previous error, or {@code null} if none.
-     * @param  newValue  the new error, or {@code null} if cleared.
-     */
-    @Override
-    @SuppressWarnings("CallToPrintStackTrace")
-    public void changed(ObservableValue<? extends Throwable> property, 
Throwable oldValue, Throwable newValue) {
-        if (newValue != null) {
-            newValue.printStackTrace();
-        }
-    }
 }

Reply via email to