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 5c3f12c80d Replace the raw text in the "Tiling" pane by a `TableView`.
5c3f12c80d is described below

commit 5c3f12c80d480421d05da246a23c5556f871cac1
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Tue Feb 24 20:09:24 2026 +0100

    Replace the raw text in the "Tiling" pane by a `TableView`.
---
 .../apache/sis/gui/coverage/BandRangeTable.java    |   8 +-
 .../apache/sis/gui/coverage/TileMatrixSetPane.java | 398 +++++++++++++++++++--
 .../apache/sis/gui/dataset/ResourceExplorer.java   |   2 +-
 .../apache/sis/gui/internal/BackgroundThreads.java |   6 +-
 .../apache/sis/gui/internal/ExceptionReporter.java |  36 +-
 5 files changed, 406 insertions(+), 44 deletions(-)

diff --git 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/BandRangeTable.java
 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/BandRangeTable.java
index 527986d747..9f7bde3f69 100644
--- 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/BandRangeTable.java
+++ 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/BandRangeTable.java
@@ -40,7 +40,7 @@ import org.apache.sis.gui.internal.Styles;
  *
  * @author  Martin Desruisseaux (Geomatys)
  */
-final class BandRangeTable implements 
Callback<TableColumn<SampleDimension,Number>, 
TableCell<SampleDimension,Number>> {
+final class BandRangeTable implements Callback<TableColumn<SampleDimension, 
Number>, TableCell<SampleDimension, Number>> {
     /**
      * Identifier of columns shown in the sample dimension table.
      */
@@ -70,7 +70,7 @@ final class BandRangeTable implements 
Callback<TableColumn<SampleDimension,Numbe
      */
     @SuppressWarnings("unchecked")     // Generic array construction.
     TableView<SampleDimension> create(final Vocabulary vocabulary) {
-        final TableView<SampleDimension> table = new TableView<>();
+        final var table = new TableView<SampleDimension>();
         table.setPrefHeight(NUM_VISIBLE_ROW * Styles.ROW_HEIGHT);
         
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY_FLEX_LAST_COLUMN);
         table.getColumns().setAll(
@@ -85,7 +85,7 @@ final class BandRangeTable implements 
Callback<TableColumn<SampleDimension,Numbe
      * Creates a new column with a title identified by the given key.
      */
     private static TableColumn<SampleDimension,String> 
createStringColumn(final Vocabulary vocabulary, final short key, final String 
id) {
-        final TableColumn<SampleDimension,String> column = new 
TableColumn<>(vocabulary.getString(key));
+        final var column = new TableColumn<SampleDimension, 
String>(vocabulary.getString(key));
         column.setCellValueFactory(BandRangeTable::getStringValue);
         column.setId(id);
         return column;
@@ -95,7 +95,7 @@ final class BandRangeTable implements 
Callback<TableColumn<SampleDimension,Numbe
      * Creates a new column with a title identified by the given key.
      */
     private TableColumn<SampleDimension,Number> createNumberColumn(final 
Vocabulary vocabulary, final short key, final String id) {
-        final TableColumn<SampleDimension,Number> column = new 
TableColumn<>(vocabulary.getString(key));
+        final var column = new TableColumn<SampleDimension, 
Number>(vocabulary.getString(key));
         column.setCellValueFactory(this::getNumberValue);
         column.setCellFactory(this);
         column.setId(id);
diff --git 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/TileMatrixSetPane.java
 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/TileMatrixSetPane.java
index d12c51bb99..27df9994e0 100644
--- 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/TileMatrixSetPane.java
+++ 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/TileMatrixSetPane.java
@@ -16,15 +16,40 @@
  */
 package org.apache.sis.gui.coverage;
 
-import javafx.scene.control.TextArea;
+import java.util.Collection;
+import java.util.Locale;
+import java.util.List;
+import javafx.collections.ObservableList;
+import javafx.beans.value.ObservableValue;
 import javafx.beans.property.ObjectProperty;
 import javafx.beans.property.SimpleObjectProperty;
-import javafx.beans.value.ObservableValue;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.Label;
+import javafx.scene.control.TableView;
+import javafx.scene.control.TableColumn;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.Priority;
 import javafx.scene.layout.Region;
+import javafx.concurrent.Task;
+import javafx.geometry.Insets;
+import javafx.util.Callback;
+import javafx.util.StringConverter;
+import org.opengis.util.GenericName;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.metadata.spatial.DimensionNameType;
+import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.storage.tiling.TileMatrix;
 import org.apache.sis.storage.tiling.TileMatrixSet;
 import org.apache.sis.storage.tiling.TiledResource;
+import org.apache.sis.coverage.grid.GridExtent;
+import org.apache.sis.util.resources.Vocabulary;
 import org.apache.sis.gui.Widget;
+import org.apache.sis.gui.internal.BackgroundThreads;
+import org.apache.sis.gui.internal.ExceptionReporter;
+import org.apache.sis.util.collection.Containers;
 
 
 /**
@@ -38,6 +63,33 @@ import org.apache.sis.gui.Widget;
  * @sinec 1.7
  */
 public class TileMatrixSetPane extends Widget {
+    /**
+     * The converter for producing string representations of the items shown 
in {@link #tileMatriceSets}.
+     * Used for the combo box which contains the list of all Tile Matrix Sets 
found in a tiled resource.
+     */
+    private static final StringConverter<TileMatrixSet> MATRIXSET_TO_STRING = 
new StringConverter<>() {
+        /** Returns the string representation of the identifier of the given 
item. */
+        @Override public String toString(final TileMatrixSet tms) {
+            if (tms != null) {
+                final GenericName identifier = tms.getIdentifier();
+                if (identifier != null) {
+                    return identifier.toString();
+                }
+            }
+            return null;
+        }
+
+        /** Not used because the combo box is non-editable. */
+        @Override public TileMatrixSet fromString(String string) {
+            return null;
+        }
+    };
+
+    /**
+     * The locale for texts in controls, or {@code null} for the default 
locale.
+     */
+    private final Locale locale;
+
     /**
      * The data shown in this widget.
      *
@@ -46,16 +98,192 @@ public class TileMatrixSetPane extends Widget {
      */
     public final ObjectProperty<TiledResource> contentProperty;
 
-    private final TextArea area = new TextArea();
+    /**
+     * List of Tile Matrix Sets (<abbr>TMS</abbr>) in the tiled resource.
+     */
+    private final ComboBox<TileMatrixSet> tileMatriceSets;
+
+    /**
+     * The label where to write the name of the Coordinate Reference System.
+     */
+    private final Label crsName;
+
+    /**
+     * Tile matrices for the currently selected item in {@link 
#tileMatriceSets}.
+     */
+    private final TableView<Row> tileMatrices;
+
+    /**
+     * The columns for the resolution along each <abbr>CRS</abbr> axis.
+     * The number of columns is the number of <abbr>CRS</abbr> dimensions.
+     */
+    private final TableColumn<Row, Double> tileResolutionColumns;
+
+    /**
+     * The columns for the number of tiles in each dimension.
+     * The number of columns is the number of grid dimensions.
+     */
+    private final TableColumn<Row, Long> tileCountColumns;
+
+    /**
+     * A row in the table of tile matrices shown by {@link #tileMatrices}.
+     * The resolution and tile count are group of columns.
+     */
+    private static final class Row {
+        /**
+         * Property for the Tile Matrix identifier.
+         */
+        private final SimpleStringProperty identifier;
+
+        /**
+         * Resolution along each <abbr>CRS</abbr> dimension.
+         * They are the values to show in the group of {@link 
#tileResolutionColumns}.
+         */
+        private final SimpleObjectProperty<Double>[] resolution;
+
+        /**
+         * Number of tiles along each grid dimension.
+         * They are the values to show in the group {@link #tileCountColumns}.
+         */
+        private final SimpleObjectProperty<Long>[] tileCount;
+
+        /**
+         * Creates a new row for the given tile matrix.
+         *
+         * @param  matrix  the matrix for which to create a row in the table.
+         */
+        @SuppressWarnings({"this-escape", "rawtypes", "unchecked"})
+        Row(final TileMatrix matrix) {
+            identifier = new SimpleStringProperty(this, "identifier");
+            final GenericName id = matrix.getIdentifier();
+            if (id != null) {
+                identifier.setValue(id.toString());
+            }
+            final double[] r = matrix.getResolution();
+            resolution = new SimpleObjectProperty[r.length];
+            for (int i=0; i<resolution.length; i++) {
+                (resolution[i] = new SimpleObjectProperty<>(this, 
"resolution")).set(r[i]);
+            }
+            final GridExtent extent = matrix.getTilingScheme().getExtent();
+            tileCount = new SimpleObjectProperty[extent.getDimension()];
+            for (int i=0; i<tileCount.length; i++) {
+                (tileCount[i] = new SimpleObjectProperty<>(this, 
"tileCount")).set(extent.getSize(i));
+            }
+        }
+
+        /**
+         * The callback for getting the identifier value of a row.
+         */
+        static final Callback<TableColumn.CellDataFeatures<Row, String>, 
ObservableValue<String>>
+                IDENTIFIER = (cell) -> cell.getValue().identifier;
+
+        /**
+         * The callback for getting resolution values in the specified 
<abbr>CRS</abbr> dimension.
+         *
+         * @param  i  a <abbr>CRS</abbr> dimension.
+         * @return getter of resolution values in the specified 
<abbr>CRS</abbr> dimension.
+         */
+        static Callback<TableColumn.CellDataFeatures<Row, Double>, 
ObservableValue<Double>> resolution(final int i) {
+            return (cell) -> {
+                final SimpleObjectProperty<Double>[] resolution = 
cell.getValue().resolution;
+                return (i >= 0 && i < resolution.length) ? resolution[i] : 
null;
+            };
+        }
+
+        /**
+         * The callback for getting tile count values of a row in the 
specified dimension.
+         *
+         * @param  i  a grid dimension.
+         * @return getter of tile count values in the specified grid dimension.
+         */
+        static Callback<TableColumn.CellDataFeatures<Row, Long>, 
ObservableValue<Long>> tileCount(final int i) {
+            return (cell) -> {
+                final SimpleObjectProperty<Long>[] tileCount = 
cell.getValue().tileCount;
+                return (i >= 0 && i < tileCount.length) ? tileCount[i] : null;
+            };
+        }
+    }
+
+    /**
+     * The pane where to layout the controls.
+     */
+    private final GridPane view;
+
+    /**
+     * Some spaces to add on the top, before the first control.
+     */
+    private static final Insets SPACE_ON_TOP = new Insets(9, 0, 0, 0);
+
+    /**
+     * Some spaces to add on the left and right sides of labels and controls.
+     */
+    private static final Insets HORIZONTAL_SPACE = new Insets(0, 12, 0, 12);
 
     /**
      * Creates an initially empty pane showing the content of a tile matrix.
+     *
+     * @param  locale  the locale for texts in controls, or {@code null} for 
the default locale.
      */
-    public TileMatrixSetPane() {
-        area.setMaxSize(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
-        area.setEditable(false);
+    @SuppressWarnings("this-escape")
+    public TileMatrixSetPane(final Locale locale) {
+        view = new GridPane();
+        view.setPadding(SPACE_ON_TOP);
+        view.setVgap(9);
+        view.setHgap(12);
+        this.locale = locale;
+        final Vocabulary vocabulary = Vocabulary.forLocale(locale);
+        /*
+         * Combox box for choosing the Tile Matrix Set.
+         * The combo box usually contains only one element.
+         */
+        {   // Block for keeping variable locale.
+            final Label label = new 
Label(vocabulary.getLabel(Vocabulary.Keys.TileMatrixSets));
+            label.setPadding(HORIZONTAL_SPACE);
+            GridPane.setHgrow(label, Priority.NEVER);
+
+            tileMatriceSets = new ComboBox<>();
+            tileMatriceSets.setEditable(false);
+            tileMatriceSets.setConverter(MATRIXSET_TO_STRING);
+            GridPane.setHgrow(tileMatriceSets, Priority.ALWAYS);
+            label.setLabelFor(tileMatriceSets);
+            view.addRow(0, label, tileMatriceSets);
+        }
+        /*
+         * Name of the Coordinate Reference System used by the currently 
selected Tile Matrix Set.
+         */
+        {   // Block for keeping variable locale.
+            final Label label = new 
Label(vocabulary.getLabel(Vocabulary.Keys.ReferenceSystem));
+            label.setPadding(HORIZONTAL_SPACE);
+            GridPane.setHgrow(label, Priority.NEVER);
+
+            crsName = new Label();
+            crsName.setMaxWidth(Double.MAX_VALUE);
+            GridPane.setHgrow(crsName, Priority.ALWAYS);
+            label.setLabelFor(crsName);
+            view.addRow(1, label, crsName);
+        }
+        /*
+         * Table of tile matrices for the currently selected Tile Matrix Set.
+         */
+        {
+            final TableColumn<Row, String> identifier;
+            identifier            = new 
TableColumn<>(vocabulary.getString(Vocabulary.Keys.Identifier));
+            tileResolutionColumns = new 
TableColumn<>(vocabulary.getString(Vocabulary.Keys.Resolution));
+            tileCountColumns      = new 
TableColumn<>(vocabulary.getString(Vocabulary.Keys.TileCount));
+            identifier.setCellValueFactory(Row.IDENTIFIER);
+
+            tileMatrices = new TableView<>();
+            tileMatrices.setEditable(false);
+            
tileMatrices.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY_SUBSEQUENT_COLUMNS);
+            tileMatrices.getColumns().setAll(List.of(identifier, 
tileResolutionColumns, tileCountColumns));
+            GridPane.setHgrow(tileMatrices, Priority.ALWAYS);
+            GridPane.setVgrow(tileMatrices, Priority.ALWAYS);
+            GridPane.setColumnSpan(tileMatrices, 2);
+            view.add(tileMatrices, 0, 2);
+        }
         contentProperty = new SimpleObjectProperty<>(this, "content");
-        contentProperty.addListener(TileMatrixSetPane::applyChange);
+        contentProperty.addListener(TileMatrixSetPane::resourceChanged);
+        
tileMatriceSets.getSelectionModel().selectedItemProperty().addListener((p,o,n) 
-> tileMatrixSetChanged(n));
     }
 
     /**
@@ -89,32 +317,154 @@ public class TileMatrixSetPane extends Widget {
      */
     @Override
     public Region getView() {
-        return area;
+        return view;
     }
 
     /**
      * Invoked when {@link #contentProperty} value changed.
+     * The Tile Matrix Sets are loaded in a background thread.
      *
      * @param  property  the property which has been modified.
-     * @param  oldValue  the old tree table.
-     * @param  newValue  the tree table to use for building new content.
+     * @param  oldValue  the old resource.
+     * @param  newValue  the resource to use for building new content.
      */
-    private static void applyChange(final ObservableValue<? extends 
TiledResource> property,
-                                    final TiledResource oldValue, final 
TiledResource newValue)
+    private static void resourceChanged(final ObservableValue<? extends 
TiledResource> property,
+                                        final TiledResource oldValue, final 
TiledResource newValue)
     {
-        final var s = (TileMatrixSetPane) ((SimpleObjectProperty) 
property).getBean();
-        if (newValue == null) {
-            s.area.setText(null);
-            return;
+        final var widget = (TileMatrixSetPane) ((SimpleObjectProperty) 
property).getBean();
+        final ComboBox<TileMatrixSet> tileSets = widget.tileMatriceSets;
+        tileSets.getItems().clear();
+        if (newValue != null) {
+            BackgroundThreads.execute(new Task<TileMatrixSet[]>() {
+                /** Fetches the Tile Matrix Sets in a background thread. */
+                @Override protected TileMatrixSet[] call() throws 
DataStoreException {
+                    return 
newValue.getTileMatrixSets().toArray(TileMatrixSet[]::new);
+                }
+
+                /** Invoked in JavaFX thread on success. */
+                @Override protected void succeeded() {
+                    tileSets.getItems().setAll(getValue());
+                    tileSets.getSelectionModel().selectFirst();
+                }
+
+                /** Invoked in JavaFX thread on failure. */
+                @Override protected void failed() {
+                    widget.reportError(getException());
+                }
+            });
         }
-        final var sb = new StringBuilder();
-        try {
-            for (TileMatrixSet tms : newValue.getTileMatrixSets()) {
-                sb.append(tms);
-            }
-        } catch (DataStoreException ex) {
-            sb.append(ex.getMessage());
+    }
+
+    /**
+     * Invoked when {@link #tileMatriceSets} selected value changed.
+     * The Tile Matrix Set properties are fetched in a background thread.
+     *
+     * @param  newValue  the Tile Matrix Set to use for building new content.
+     */
+    private void tileMatrixSetChanged(final TileMatrixSet newValue) {
+        tileMatrices.getItems().clear();
+        crsName.setText(null);
+        if (newValue != null) {
+            BackgroundThreads.execute(new Task<TileMatrix[]>() {
+                /** The coordinate reference system. */
+                private CoordinateReferenceSystem crs;
+
+                /** Name of the Coordinate Reference System. */
+                private String crsDisplayName;
+
+                /** The grid extent of the tiling scheme, using the first row 
as a representative value. */
+                private GridExtent tilingScheme;
+
+                /** Fetches the Tile Matrices in a background thread. */
+                @Override protected TileMatrix[] call() {
+                    crs = newValue.getCoordinateReferenceSystem();
+                    if (crs != null) {
+                        crsDisplayName = IdentifiedObjects.getDisplayName(crs, 
locale);
+                    }
+                    final Collection<? extends TileMatrix> matrices = 
newValue.getTileMatrices().values();
+                    final TileMatrix first = Containers.peekFirst(matrices);
+                    if (first != null) {
+                        tilingScheme = first.getTilingScheme().getExtent();
+                    }
+                    return matrices.toArray(TileMatrix[]::new);
+                }
+
+                /** Invoked in JavaFX thread on success. */
+                @Override protected void succeeded() {
+                    crsName.setText(crsDisplayName);
+                    final TileMatrix[] matrices = getValue();
+                    final Row[] rows = new Row[matrices.length];
+                    int crsDimension = 0, gridDimension = 0;
+                    for (int i=0; i<rows.length; i++) {
+                        final var row = new Row(matrices[i]);
+                        crsDimension  = Math.max(crsDimension, 
row.resolution.length);
+                        gridDimension = Math.max(gridDimension, 
row.tileCount.length);
+                        rows[i] = row;
+                    }
+                    tileMatrices.getItems().setAll(rows);
+                    /*
+                     * Add or remove columns for the CRS dimensions.
+                     */
+                    {
+                        final CoordinateSystem cs = (crs != null) ? 
crs.getCoordinateSystem() : null;
+                        final ObservableList<TableColumn<Row, ?>> columns = 
tileResolutionColumns.getColumns();
+                        for (int i=0; i<crsDimension; i++) {
+                            final String header = (i < cs.getDimension())
+                                    ? cs.getAxis(i).getAbbreviation() : 
String.valueOf(i);
+                            if (i < columns.size()) {
+                                columns.get(i).setText(header);
+                            } else {
+                                final var column = new TableColumn<Row, 
Double>(header);
+                                column.setCellValueFactory(Row.resolution(i));
+                                columns.add(column);
+                            }
+                        }
+                        final int size = columns.size();
+                        if (crsDimension < size) {
+                            columns.remove(crsDimension, size);
+                        }
+                    }
+                    /*
+                     * Add or remove columns for the grid dimensions.
+                     * We use the first row for getting the grid axis 
identifiers.
+                     */
+                    final ObservableList<TableColumn<Row, ?>> columns = 
tileCountColumns.getColumns();
+                    if (rows.length != 0) {
+                        for (int i=0; i<gridDimension; i++) {
+                            String header = null;
+                            if (i < tilingScheme.getDimension()) {
+                                header = 
tilingScheme.getAxisType(i).flatMap(DimensionNameType::identifier).orElse(null);
+                            }
+                            if (header == null) {
+                                header = String.valueOf(i);
+                            }
+                            if (i < columns.size()) {
+                                columns.get(i).setText(header);
+                            } else {
+                                final var column = new TableColumn<Row, 
Long>(header);
+                                column.setCellValueFactory(Row.tileCount(i));
+                                columns.add(column);
+                            }
+                        }
+                    }
+                    final int size = columns.size();
+                    if (crsDimension < size) {
+                        columns.remove(crsDimension, size);
+                    }
+                }
+
+                /** Invoked in JavaFX thread on failure. */
+                @Override protected void failed() {
+                    reportError(getException());
+                }
+            });
         }
-        s.area.setText(sb.toString());
+    }
+
+    /**
+     * Invoked when a background task failed.
+     */
+    private void reportError(final Throwable exception) {
+        ExceptionReporter.canNotUseResource(view, exception);
     }
 }
diff --git 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/ResourceExplorer.java
 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/ResourceExplorer.java
index 15b183dce3..a2c8c5f3fb 100644
--- 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/ResourceExplorer.java
+++ 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/dataset/ResourceExplorer.java
@@ -204,7 +204,7 @@ public class ResourceExplorer extends Widget {
          */
         metadata = new MetadataSummary();
         nativeMetadata = new MetadataTree(metadata);
-        tiling = new TileMatrixSetPane();
+        tiling = new TileMatrixSetPane(resources.locale);
         final var logging = new LogViewer(vocabulary);
         selectedResource = new ReadOnlyObjectWrapper<>(this, 
"selectedResource");
         logging.source.bind(selectedResource);
diff --git 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/BackgroundThreads.java
 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/BackgroundThreads.java
index 4020fd60db..1a2da2649a 100644
--- 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/BackgroundThreads.java
+++ 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/BackgroundThreads.java
@@ -113,7 +113,7 @@ public final class BackgroundThreads extends AtomicInteger 
implements ThreadFact
              * are doing below is guaranteed to be executed after the calls 
done by `task.run()`.
              * The timeout is low because the tasks on JavaFX threads are 
supposed to be very short.
              */
-            final CountDownLatch c = new CountDownLatch(1);
+            final var c = new CountDownLatch(1);
             Platform.runLater(c::countDown);
             try {
                 c.await(5, TimeUnit.SECONDS);
@@ -133,7 +133,7 @@ public final class BackgroundThreads extends AtomicInteger 
implements ThreadFact
      * @return the task result, or {@code null} if an error occurred.
      */
     public static <V> V runAndWaitDialog(final Callable<V> task) {
-        final FutureTask<V> f = new FutureTask<>(task);
+        final var f = new FutureTask<V>(task);
         Platform.runLater(f);
         try {
             return f.get();
@@ -155,7 +155,7 @@ public final class BackgroundThreads extends AtomicInteger 
implements ThreadFact
      * @throws Exception if the task threw an exception.
      */
     public static <V> V runAndWait(final Callable<V> task) throws Exception {
-        final FutureTask<V> f = new FutureTask<>(task);
+        final var f = new FutureTask<V>(task);
         Platform.runLater(f);
         try {
             return f.get();
diff --git 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/ExceptionReporter.java
 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/ExceptionReporter.java
index c508db4c12..94e10f7ffb 100644
--- 
a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/ExceptionReporter.java
+++ 
b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/internal/ExceptionReporter.java
@@ -96,7 +96,7 @@ public final class ExceptionReporter extends Widget {
     public ExceptionReporter(final Throwable exception) {
         this.exception = exception;
         trace = new Text(getStackTrace(exception));
-        final ScrollPane pane = new ScrollPane(trace);
+        final var pane = new ScrollPane(trace);
         pane.setFitToWidth(true);
         pane.setFitToHeight(true);
         pane.setPadding(MARGIN);
@@ -132,7 +132,7 @@ public final class ExceptionReporter extends Widget {
      * @return the stack trace.
      */
     public static String getStackTrace(final Throwable exception) {
-        final StringWriter buffer = new StringWriter();
+        final var buffer = new StringWriter();
         exception.printStackTrace(new PrintWriter(buffer));
         return buffer.toString();
     }
@@ -196,8 +196,11 @@ public final class ExceptionReporter extends Widget {
      * @param  exception  the error that occurred.
      */
     public static void canNotReadFile(final Node owner, final String file, 
final Throwable exception) {
-        show(GUIUtilities.getWindow(owner), Resources.Keys.ErrorOpeningFile, 
Resources.Keys.CanNotReadFile_1,
-                new Object[] {file}, exception);
+        show(GUIUtilities.getWindow(owner),
+                Resources.Keys.ErrorOpeningFile,
+                Resources.Keys.CanNotReadFile_1,
+                new Object[] {file},
+                exception);
     }
 
     /**
@@ -209,8 +212,11 @@ public final class ExceptionReporter extends Widget {
      * @param  exception  the error that occurred.
      */
     public static void canNotCloseFile(final Node owner, final String file, 
final Throwable exception) {
-        show(GUIUtilities.getWindow(owner), Resources.Keys.ErrorClosingFile, 
Resources.Keys.CanNotClose_1,
-                new Object[] {file}, exception);
+        show(GUIUtilities.getWindow(owner),
+                Resources.Keys.ErrorClosingFile,
+                Resources.Keys.CanNotClose_1,
+                new Object[] {file},
+                exception);
     }
 
     /**
@@ -222,8 +228,11 @@ public final class ExceptionReporter extends Widget {
      * @param  exception  the error that occurred.
      */
     public static void canNotCreateCRS(final Window owner, final String code, 
final Throwable exception) {
-        show(owner, Resources.Keys.ErrorCreatingCRS, 
Resources.Keys.CanNotCreateCRS_1,
-                new Object[] {code}, exception);
+        show(owner,
+                Resources.Keys.ErrorCreatingCRS,
+                Resources.Keys.CanNotCreateCRS_1,
+                new Object[] {code},
+                exception);
     }
 
     /**
@@ -234,8 +243,11 @@ public final class ExceptionReporter extends Widget {
      * @param  exception  the error that occurred.
      */
     public static void canNotUseResource(final Node owner, final Throwable 
exception) {
-        show(GUIUtilities.getWindow(owner), Resources.Keys.ErrorDataAccess, 
Resources.Keys.ErrorDataAccess,
-                new Object[0], exception);
+        show(GUIUtilities.getWindow(owner),
+                Resources.Keys.ErrorDataAccess,
+                Resources.Keys.ErrorDataAccess,
+                new Object[0],
+                exception);
     }
 
     /**
@@ -303,7 +315,7 @@ public final class ExceptionReporter extends Widget {
             alert = new Alert(Alert.AlertType.ERROR);
             alert.initOwner(owner);
             alert.setOnHidden((event) -> currentlyShown = null);
-            final ExceptionReporter content = new ExceptionReporter(exception);
+            final var content = new ExceptionReporter(exception);
             final DialogPane pane = alert.getDialogPane();
             pane.setExpandableContent(content.getView());
             pane.setPrefWidth(650);
@@ -335,7 +347,7 @@ public final class ExceptionReporter extends Widget {
      * @param event ignored.
      */
     private void copy(final ActionEvent event) {
-        final ClipboardContent content = new ClipboardContent();
+        final var content = new ClipboardContent();
         content.putString(trace.getText());
         Clipboard.getSystemClipboard().setContent(content);
     }

Reply via email to