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


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new dabc81231b Try to be more robust to the GDAL convention in netcDF 
file. This convention uses a "GeoTransform" attribute instead of coordinate 
axes defined by variables. A difficulty is that this attribute is often 2D even 
when the variables have more dimensions.
dabc81231b is described below

commit dabc81231bc6fa87d304ab663cb6a5f4231f8b10
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Thu Jul 31 19:57:50 2025 +0200

    Try to be more robust to the GDAL convention in netcDF file.
    This convention uses a "GeoTransform" attribute instead of coordinate axes 
defined by variables.
    A difficulty is that this attribute is often 2D even when the variables 
have more dimensions.
---
 .../apache/sis/coverage/grid/SliceGeometry.java    |   2 +-
 .../iso/maintenance/DefaultScopeDescription.java   |   5 +-
 .../apache/sis/profile/japan/netcdf/GCOM_C.java    |   4 +-
 .../apache/sis/storage/netcdf/base/Convention.java |  30 ++---
 .../sis/storage/netcdf/base/GridMapping.java       | 135 ++++++++++++++++-----
 .../apache/sis/gui/coverage/CoverageCanvas.java    |  10 +-
 6 files changed, 131 insertions(+), 55 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/SliceGeometry.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/SliceGeometry.java
index 82d3e37af5..d27bbd82c8 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/SliceGeometry.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/SliceGeometry.java
@@ -316,7 +316,7 @@ final class SliceGeometry implements 
Function<RenderedImage, GridGeometry> {
         }
         numRow += derivative.getNumRow();
         if (dimCRS < 0) {
-            dimCRS = gridDimensions.length + (gridToCRS.getTargetDimensions() 
- gridToCRS.getSourceDimensions());
+            dimCRS = gridDimensions.length;
         }
         /*
          * Search for the greatest scale coefficient. For the greatest value, 
take the row as the target
diff --git 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/maintenance/DefaultScopeDescription.java
 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/maintenance/DefaultScopeDescription.java
index 22acce25bf..c3237e3320 100644
--- 
a/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/maintenance/DefaultScopeDescription.java
+++ 
b/endorsed/src/org.apache.sis.metadata/main/org/apache/sis/metadata/iso/maintenance/DefaultScopeDescription.java
@@ -157,7 +157,6 @@ public class DefaultScopeDescription extends ISOMetadata 
implements ScopeDescrip
         if (object != null) {
             for (byte i=DATASET; i<=OTHER; i++) {
                 Collection<? extends CharSequence> props = null;
-                Object value = null;
                 switch (i) {
                     case DATASET:             value = object.getDataset();     
       break;
                     case FEATURES:            props = object.getFeatures();    
       break;
@@ -171,8 +170,7 @@ public class DefaultScopeDescription extends ISOMetadata 
implements ScopeDescrip
                     value = copySet(props, CharSequence.class);
                 }
                 if (value != null) {
-                    this.value = value;
-                    this.property = i;
+                    property = i;
                     break;
                 }
             }
@@ -219,6 +217,7 @@ public class DefaultScopeDescription extends ISOMetadata 
implements ScopeDescrip
      * or an unmodifiable empty set if another value is defined.
      */
     private Set<CharSequence> getProperty(final byte code) {
+        @SuppressWarnings("LocalVariableHidesMemberVariable")
         final Object value = this.value;
         if (value != null) {
             if (property == code) {
diff --git 
a/endorsed/src/org.apache.sis.profile.japan/main/org/apache/sis/profile/japan/netcdf/GCOM_C.java
 
b/endorsed/src/org.apache.sis.profile.japan/main/org/apache/sis/profile/japan/netcdf/GCOM_C.java
index c538095ad7..746eb93493 100644
--- 
a/endorsed/src/org.apache.sis.profile.japan/main/org/apache/sis/profile/japan/netcdf/GCOM_C.java
+++ 
b/endorsed/src/org.apache.sis.profile.japan/main/org/apache/sis/profile/japan/netcdf/GCOM_C.java
@@ -345,7 +345,7 @@ public final class GCOM_C extends Convention {
      */
     @Override
     public Set<String> nameOfMappingNode(final Variable data) {
-        final Set<String> names = new LinkedHashSet<>(4);
+        final var names = new LinkedHashSet<String>(4);
         names.add(GEOMETRY_DATA);
         names.addAll(super.nameOfMappingNode(data));            // Fallback if 
geometry data does not exist.
         return names;
@@ -390,7 +390,7 @@ public final class GCOM_C extends Convention {
         } else {
             return super.projection(node);
         }
-        final Map<String,Object> definition = new HashMap<>(4);
+        final var definition = new HashMap<String,Object>(4);
         definition.put(CF.GRID_MAPPING_NAME, method);
         definition.put(CONVERSION_NAME, name);
         return definition;
diff --git 
a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/Convention.java
 
b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/Convention.java
index 1ea0d3a379..a15188b97c 100644
--- 
a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/Convention.java
+++ 
b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/Convention.java
@@ -18,7 +18,6 @@ package org.apache.sis.storage.netcdf.base;
 
 import java.util.Map;
 import java.util.Set;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.ServiceLoader;
@@ -487,12 +486,12 @@ public class Convention {
         if (method == null) {
             return null;
         }
-        final var definition = new HashMap<String,Object>();
+        final var definition = new LinkedHashMap<String,Object>();
         definition.put(CF.GRID_MAPPING_NAME, method);
         for (final String name : node.getAttributeNames()) try {
-            final String ln = name.toLowerCase(Decoder.DATA_LOCALE);
+            final String nameLC = name.toLowerCase(Decoder.DATA_LOCALE);
             Object value;
-            switch (ln) {
+            switch (nameLC) {
                 case CF.GRID_MAPPING_NAME: continue;        // Already stored.
                 case TOWGS84: {
                     /*
@@ -508,23 +507,24 @@ public class Convention {
                     break;
                 }
                 default: {
-                    if (ln.endsWith(NAME_SUFFIX)) {
+                    if (nameLC.endsWith(NAME_SUFFIX)) {
                         value = node.getAttributeAsString(name);
                         if (value == null) continue;
-                    }
-                    /*
-                     * Assume that all map projection parameters in netCDF 
files are numbers or array of numbers.
-                     * If values are array, then they are converted to an 
array of {@code double[]} type.
-                     */
-                    value = node.getAttributeValue(name);
-                    if (value == null) continue;
-                    if (value instanceof Vector) {
-                        value = ((Vector) value).doubleValues();
+                    } else {
+                        /*
+                         * Assume that all map projection parameters in netCDF 
files are numbers or array of numbers.
+                         * If values are array, then they are converted to an 
array of {@code double[]} type.
+                         */
+                        value = node.getAttributeValue(name);
+                        if (value == null) continue;
+                        if (value instanceof Vector) {
+                            value = ((Vector) value).doubleValues();
+                        }
                     }
                     break;
                 }
             }
-            if (definition.putIfAbsent(name, value) != null) {
+            if (definition.putIfAbsent(nameLC, value) != null) {
                 node.error(Convention.class, "projection", null, 
Errors.Keys.DuplicatedIdentifier_1, name);
             }
         } catch (NumberFormatException e) {
diff --git 
a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/GridMapping.java
 
b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/GridMapping.java
index bc1f628017..9c8bc924ba 100644
--- 
a/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/GridMapping.java
+++ 
b/endorsed/src/org.apache.sis.storage.netcdf/main/org/apache/sis/storage/netcdf/base/GridMapping.java
@@ -59,17 +59,20 @@ import org.apache.sis.referencing.cs.AxesConvention;
 import org.apache.sis.referencing.datum.BursaWolfParameters;
 import org.apache.sis.referencing.datum.DefaultGeodeticDatum;
 import org.apache.sis.referencing.operation.matrix.Matrix3;
+import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.referencing.operation.transform.MathTransforms;
 import org.apache.sis.referencing.operation.transform.TransformSeparator;
 import org.apache.sis.referencing.operation.provider.PseudoPlateCarree;
 import org.apache.sis.referencing.privy.AxisDirections;
 import org.apache.sis.referencing.privy.AffineTransform2D;
+import org.apache.sis.referencing.privy.ReferencingUtilities;
 import org.apache.sis.storage.DataStoreContentException;
 import org.apache.sis.storage.netcdf.internal.Resources;
 import org.apache.sis.coverage.grid.GridGeometry;
 import org.apache.sis.coverage.grid.GridExtent;
 import org.apache.sis.coverage.grid.PixelInCell;
 import org.apache.sis.system.Modules;
+import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.Numbers;
@@ -89,8 +92,9 @@ import org.opengis.referencing.datum.DatumEnsemble;
 
 /**
  * Helper object for creating a {@link GridGeometry} instance defined by 
attributes on a variable.
- * Those attributes are defined by CF-conventions, but some other non-CF 
attributes are also in usage
- * (e.g. GDAL or ESRI conventions). This class uses a different approach than 
{@link CRSBuilder},
+ * Those attributes are defined by <abbr>CF</abbr>-conventions, but some other 
non-<abbr>CF</abbr>
+ * attributes are also recognized (e.g. <abbr>GDAL</abbr> and 
<abbr>ESRI</abbr> conventions).
+ * This class uses a different approach than {@link CRSBuilder},
  * which creates Coordinate Reference Systems by inspecting coordinate system 
axes.
  *
  * @author  Martin Desruisseaux (Geomatys)
@@ -98,6 +102,12 @@ import org.opengis.referencing.datum.DatumEnsemble;
  * @see <a 
href="http://cfconventions.org/cf-conventions/cf-conventions.html#grid-mappings-and-projections";>CF-conventions</a>
  */
 final class GridMapping {
+    /**
+     * Names of some (not all) attributes where the <abbr>CRS</abbr> may be 
encoded in <abbr>WKT</abbr> format.
+     * Values must be in lower-cases because {@link 
Convention#projection(Node)} converts names to lower cases.
+     */
+    private static final String CRS_WKT = "crs_wkt", SPATIAL_REF = 
"spatial_ref";
+
     /**
      * The variable on which projection parameters are defined as attributes.
      * This is typically an empty variable referenced by the value of the
@@ -109,8 +119,8 @@ final class GridMapping {
 
     /**
      * The Coordinate Reference System inferred from grid mapping attribute 
values, or {@code null} if none.
-     * This CRS may have been constructed from Well Known Text or EPSG codes 
declared in {@code "spatial_ref"},
-     * {@code "ESRI_pe_string"} or {@code "EPSG_code"} attributes.
+     * This <abbr>CRS</abbr> may have been constructed from Well Known Text or 
<abbr>EPSG</abbr> codes
+     * declared in {@value #SPATIAL_REF}, {@code "ESRI_pe_string"} or {@code 
"EPSG_code"} attributes.
      *
      * <h4>Usage note</h4>
      * This is built from different information than the one used by {@link 
CRSBuilder},
@@ -121,8 +131,9 @@ final class GridMapping {
     private CoordinateReferenceSystem crs;
 
     /**
-     * The <i>grid to CRS</i> transform, or {@code null} if none. This 
information is usually not specified
-     * except when using GDAL conventions. If {@code null}, then the transform 
should be inferred by {@link Grid}.
+     * The <i>grid to CRS</i> transform, or {@code null} if none.
+     * This information is usually not specified except when using 
<abbr>GDAL</abbr> conventions.
+     * If {@code null}, then the transform should be inferred by {@link Grid}.
      */
     private MathTransform gridToCRS;
 
@@ -185,8 +196,8 @@ final class GridMapping {
 
     /**
      * Parses the map projection parameters defined as attribute associated to 
the given variable.
-     * This method tries to parse CF-compliant attributes first. If none are 
found, non-standard
-     * extensions (for example GDAL usage) are tried next.
+     * This method tries to parse <abbr>CF</abbr>-compliant attributes, 
potentially mixed with
+     * non-standard extensions (for example <abbr>GDAL</abbr>).
      */
     private static GridMapping parse(final Node mapping) {
         final var gm = new GridMapping(mapping);
@@ -228,7 +239,21 @@ final class GridMapping {
                     if (value instanceof Number || value instanceof double[] 
|| value instanceof float[]) {
                         it.remove();
                         parameters.parameter(name).setValue(value);
-                    } else if (value instanceof String && 
!name.endsWith(Convention.NAME_SUFFIX)) {
+                    } else if (value instanceof String) {
+                        final var text = (String) value;
+                        if (name.endsWith(Convention.NAME_SUFFIX)) {
+                            continue;
+                        }
+                        switch (name) {
+                            case CRS_WKT:
+                            case SPATIAL_REF: continue;     // Will be parsed 
after this loop.
+                            case "geotransform": {          // "GeoTransform" 
made lower-case.
+                                if (parseGeoTransform(null, text)) {
+                                    it.remove();
+                                }
+                                continue;
+                            }
+                        }
                         /*
                          * In principle we should ignore non-numeric 
parameters. But in practice, some badly encoded
                          * netCDF files store parameters as strings instead of 
numbers. If the parameter name is
@@ -243,15 +268,22 @@ final class GridMapping {
                         final Class<?> type = 
parameter.getDescriptor().getValueClass();
                         if (Numbers.isNumber(type)) {
                             it.remove();
-                            parameter.setValue(Double.parseDouble((String) 
value));
+                            parameter.setValue(Double.parseDouble(text));
                         } else if (Numbers.isNumber(type.getComponentType())) {
                             it.remove();
-                            parameter.setValue(parseDoubles((String) value), 
null);
+                            parameter.setValue(parseDoubles(text), null);
                         }
                     }
-                } catch (IllegalArgumentException ex) {                     // 
Includes NumberFormatException.
-                    warning(mapping, ex, null, 
Resources.Keys.CanNotSetProjectionParameter_5,
-                            mapping.decoder.getFilename(), mapping.getName(), 
name, value, ex.getLocalizedMessage());
+                } catch (IllegalArgumentException ex) {     // Includes 
NumberFormatException.
+                    warning(mapping,
+                            ex,
+                            null,       // Default to `Resources` bundle.
+                            Resources.Keys.CanNotSetProjectionParameter_5,
+                            mapping.decoder.getFilename(),
+                            mapping.getName(),
+                            name,
+                            value,
+                            ex.getLocalizedMessage());
                 }
             }
             /*
@@ -282,8 +314,8 @@ final class GridMapping {
              * obvious (except for CompoundCRS).
              */
             final var done = new ArrayList<String>(2);
-            setOrVerifyWKT(definition, "crs_wkt", done);
-            setOrVerifyWKT(definition, "spatial_ref", done);
+            setOrVerifyWKT(definition, CRS_WKT, done);
+            setOrVerifyWKT(definition, SPATIAL_REF, done);
             /*
              * Report all projection parameters that have not been used. If 
the map is not rendered
              * at expected location, it may be because we have ignored some 
important parameters.
@@ -297,7 +329,11 @@ final class GridMapping {
              * Build the "grid to CRS" if present. This is not defined by 
CF-convention,
              * but may be present in some non-CF conventions.
              */
-            gridToCRS = mapping.decoder.convention().gridToCRS(mapping, 
baseToCRS);
+            if (gridToCRS == null) {
+                gridToCRS = mapping.decoder.convention().gridToCRS(mapping, 
baseToCRS);
+            } else {
+                gridToCRS = MathTransforms.concatenate(gridToCRS, baseToCRS);
+            }
             return true;
         } catch (ClassCastException | IllegalArgumentException | 
FactoryException | TransformException e) {
             warningInMapping(mapping, e, Resources.Keys.CanNotCreateCRS_3, 
null);
@@ -400,7 +436,10 @@ final class GridMapping {
          */
         if (isSpecified) {
             final Map<String,?> properties = properties(definition, 
Convention.GEOGRAPHIC_CRS_NAME, main, datum);
-            return decoder.getCRSFactory().createGeographicCRS(properties, 
datum, ensemble,
+            return decoder.getCRSFactory().createGeographicCRS(
+                    properties,
+                    datum,
+                    ensemble,
                     defaultDefinitions.geographic().getCoordinateSystem());
         } else {
             return defaultDefinitions.geographic();
@@ -471,9 +510,13 @@ final class GridMapping {
             }
             if (crs == null) {
                 crs = check;
-            } else if (!Utilities.equalsIgnoreMetadata(crs, check)) {
-                warning(mapping, null, null, Resources.Keys.InconsistentCRS_2,
-                        mapping.decoder.getFilename(), mapping.getName());
+            } else if (!Utilities.deepEquals(crs, check, 
ComparisonMode.ALLOW_VARIANT)) {
+                warning(mapping,        // Node
+                        null,           // Exception
+                        null,           // Resources
+                        Resources.Keys.InconsistentCRS_2,
+                        mapping.decoder.getFilename(),
+                        mapping.getName());
             }
         }
     }
@@ -492,8 +535,14 @@ final class GridMapping {
      * @return whether this method found grid geometry attributes.
      */
     private boolean parseGeoTransform() {
-        final String wkt = mapping.getAttributeAsString("spatial_ref");
-        final String gtr = mapping.getAttributeAsString("GeoTransform");
+        return parseGeoTransform(mapping.getAttributeAsString(SPATIAL_REF),
+                                 mapping.getAttributeAsString("GeoTransform"));
+    }
+
+    /**
+     * Implementation of {@link #parseGeoTransform()} with given attribute 
values.
+     */
+    private boolean parseGeoTransform(final String wkt, final String gtr) {
         short message = Resources.Keys.CanNotCreateCRS_3;
         boolean done = false;
         try {
@@ -617,19 +666,41 @@ final class GridMapping {
     }
 
     /**
-     * Creates a new grid geometry with the extent of the given variable and a 
potentially null CRS.
+     * Creates a new grid geometry with the extent of the given variable and a 
potentially null <abbr>CRS</abbr>.
      * This method should be invoked only as a fallback when no existing 
{@link GridGeometry} can be used.
      * The CRS and "grid to CRS" transform are null, unless some partial 
information was found for example
      * as WKT string.
      */
     final GridGeometry createGridCRS(final Variable variable) {
         final List<Dimension> dimensions = variable.getGridDimensions();
-        final long[] upper = new long[dimensions.size()];
-        for (int i=0; i<upper.length; i++) {
-            final int d = (upper.length - 1) - i;           // Convert CRS 
dimension to netCDF dimension.
+        final int srcDim = dimensions.size();
+        final long[] upper = new long[srcDim];
+        for (int i=0; i<srcDim; i++) {
+            final int d = (srcDim - 1) - i;         // Convert CRS dimension 
to netCDF dimension.
             upper[i] = dimensions.get(d).length();
         }
-        return new GridGeometry(new GridExtent(null, null, upper, false), 
PixelInCell.CELL_CENTER, gridToCRS, crs);
+        MathTransform implicitG2C = gridToCRS;
+        CoordinateReferenceSystem implicitCRS = crs;
+        if (implicitG2C != null) {
+            implicitG2C = MathTransforms.concatenate(
+                    changeOfDimension(srcDim, 
implicitG2C.getSourceDimensions()),
+                    implicitG2C,
+                    changeOfDimension(implicitG2C.getTargetDimensions(),
+                                      
ReferencingUtilities.getDimension(implicitCRS)));
+        }
+        final var extent = new GridExtent(null, null, upper, false);
+        return new GridGeometry(extent, PixelInCell.CELL_CENTER, implicitG2C, 
implicitCRS);
+    }
+
+    /**
+     * Returns a transform for changing the number of dimensions of a math 
transform.
+     * For convenience, a target number of dimensions of 0 means no change.
+     */
+    private static MathTransform changeOfDimension(final int srcDim, final int 
tgtDim) {
+        if (tgtDim == srcDim || tgtDim == 0) {
+            return MathTransforms.identity(srcDim);
+        }
+        return MathTransforms.linear(Matrices.createDimensionSelect(srcDim, 
ArraysExt.range(0, tgtDim)));
     }
 
     /**
@@ -674,7 +745,7 @@ final class GridMapping {
                     if (firstAffectedCoordinate < 0) {
                         firstAffectedCoordinate = 0;
                         if (isWKT && crs != null) {
-                            explicitCRS = crs;                         // If 
specified by WKT, use the CRS verbatim.
+                            explicitCRS = crs;          // If specified by 
WKT, use the CRS verbatim.
                         }
                     }
                 }
@@ -691,13 +762,13 @@ final class GridMapping {
                 }
                 isSameGrid = implicitCRS.equals(explicitCRS);
                 if (isSameGrid) {
-                    explicitCRS = implicitCRS;                                 
// Keep existing instance if appropriate.
+                    explicitCRS = implicitCRS;          // Keep existing 
instance if appropriate.
                 }
             }
         }
         /*
          * Perform the same substitution as above, but in the "grid to CRS" 
transform. Note that the "grid to CRS"
-         * is usually not specified, so the block performing substitution will 
rarely be executed. If executed, then
+         * is usually not specified, so the block performing substitution will 
rarely be executed. If executed,
          * then we need to perform selection in target dimensions (not source 
dimensions) because the first affected
          * coordinate computed above is in CRS dimension, which is the target 
of "grid to CRS" transform.
          */
@@ -725,7 +796,7 @@ final class GridMapping {
                 components = ArraysExt.resize(components, count);
                 explicitG2C = MathTransforms.compound(components);
                 if (implicitG2C.equals(explicitG2C)) {
-                    explicitG2C = implicitG2C;                                 
// Keep using existing instance if appropriate.
+                    explicitG2C = implicitG2C;          // Keep using existing 
instance if appropriate.
                 } else {
                     isSameGrid = false;
                 }
diff --git 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/CoverageCanvas.java
 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/CoverageCanvas.java
index 965841c4a6..a60d484aee 100644
--- 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/CoverageCanvas.java
+++ 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/CoverageCanvas.java
@@ -77,6 +77,7 @@ import org.apache.sis.gui.internal.GUIUtilities;
 import org.apache.sis.gui.internal.LogHandler;
 import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.Debug;
+import org.apache.sis.util.Exceptions;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.privy.CollectionsExt;
 import org.apache.sis.io.TableAppender;
@@ -656,8 +657,13 @@ public class CoverageCanvas extends MapCanvasAWT {
                  */
                 @Override protected void succeeded() {
                     runAfterRendering(() -> {
-                        setNewSource(getValue(), ranges, zoom);
-                        requestRepaint();                   // Cause `Worker` 
class to be executed.
+                        try {
+                            setNewSource(getValue(), ranges, zoom);
+                            requestRepaint();                   // Cause 
`Worker` class to be executed.
+                        } catch (RuntimeException ex) {         // Mostly for 
`BackingStoreException`.
+                            clear();
+                            ExceptionReporter.canNotUseResource(fixedPane, 
Exceptions.unwrap(ex));
+                        }
                     });
                 }
 

Reply via email to