sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 02/02: Better catching of exceptions to be reported to user.
Date Wed, 10 Feb 2021 15:11:52 GMT
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 <martin.desruisseaux@geomatys.com>
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();
-        }
-    }
 }


Mime
View raw message