You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2020/01/31 19:16:51 UTC
[sis] branch geoapi-4.0 updated: List the sample dimensions in
CoverageExplorer.
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 5e91876 List the sample dimensions in CoverageExplorer.
5e91876 is described below
commit 5e91876fd2255373ca0a339e10f8b6cfe0f98d07
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Fri Jan 31 20:16:37 2020 +0100
List the sample dimensions in CoverageExplorer.
---
.../apache/sis/gui/coverage/CoverageExplorer.java | 49 ++++++++++++++++++---
.../java/org/apache/sis/gui/coverage/GridView.java | 12 +++---
.../org/apache/sis/gui/coverage/ImageLoader.java | 14 +++++-
.../org/apache/sis/gui/coverage/ImageRequest.java | 50 ++++++++++++++++++++++
.../apache/sis/internal/gui/ExceptionReporter.java | 30 ++++++++++---
.../org/apache/sis/internal/gui/Resources.java | 10 +++++
.../apache/sis/internal/gui/Resources.properties | 2 +
.../sis/internal/gui/Resources_fr.properties | 2 +
.../org/apache/sis/util/resources/Vocabulary.java | 5 +++
.../sis/util/resources/Vocabulary.properties | 1 +
.../sis/util/resources/Vocabulary_fr.properties | 1 +
11 files changed, 157 insertions(+), 19 deletions(-)
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageExplorer.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageExplorer.java
index 2aebfda..d45a69a 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageExplorer.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageExplorer.java
@@ -16,20 +16,24 @@
*/
package org.apache.sis.gui.coverage;
+import java.util.Locale;
import java.awt.image.RenderedImage;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue;
+import javafx.collections.ObservableList;
import javafx.scene.control.Accordion;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.SplitPane;
import javafx.scene.control.TitledPane;
+import javafx.scene.control.ListCell;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import org.apache.sis.coverage.SampleDimension;
import org.apache.sis.coverage.grid.GridCoverage;
import org.apache.sis.internal.gui.Styles;
+import org.apache.sis.util.resources.Vocabulary;
/**
@@ -78,6 +82,8 @@ public class CoverageExplorer {
public CoverageExplorer() {
gridView = new GridView();
sampleDimensions = new ListView<>();
+ sampleDimensions.setCellFactory(SampleDimensionCell::new);
+ final Vocabulary vocabulary = Vocabulary.getResources((Locale) null);
/*
* Create the "Coverage" pane with the following controls:
* - Coverage domain as a list of CRS dimensions with two of them selected (TODO).
@@ -85,13 +91,13 @@ public class CoverageExplorer {
*/
final VBox coveragePane;
{ // Block for making variables locale to this scope.
- final Label label = new Label("Sample dimensions:");
+ final Label label = new Label(vocabulary.getString(Vocabulary.Keys.SampleDimensions));
label.setLabelFor(sampleDimensions);
coveragePane = new VBox(label, sampleDimensions);
}
final Accordion controls = new Accordion(
- new TitledPane("Coverage", coveragePane)
+ new TitledPane(vocabulary.getString(Vocabulary.Keys.Coverage), coveragePane)
// TODO: more controls to be added in a future version.
);
content = new SplitPane(controls, gridView);
@@ -100,7 +106,7 @@ public class CoverageExplorer {
content.setDividerPosition(0, Styles.INITIAL_SPLIT);
coverageProperty = new SimpleObjectProperty<>(this, "coverage");
- coverageProperty.addListener(this::coverageDefined);
+ coverageProperty.addListener(this::onCoverageSpecified);
}
/**
@@ -152,6 +158,7 @@ public class CoverageExplorer {
if (source == null) {
setCoverage((GridCoverage) null);
} else {
+ source.addListener(this);
gridView.setImage(source);
}
}
@@ -163,8 +170,8 @@ public class CoverageExplorer {
* @param previous ignored.
* @param coverage the new coverage.
*/
- private void coverageDefined(final ObservableValue<? extends GridCoverage> property,
- final GridCoverage previous, final GridCoverage coverage)
+ private void onCoverageSpecified(final ObservableValue<? extends GridCoverage> property,
+ final GridCoverage previous, final GridCoverage coverage)
{
gridView.setImage((RenderedImage) null);
if (coverage != null) {
@@ -174,4 +181,36 @@ public class CoverageExplorer {
sampleDimensions.getItems().clear();
}
}
+
+ /**
+ * Invoked in JavaFX thread by {@link ImageLoader} when the coverage has been read.
+ * This method does not set the image because it will be set by {@link ImageLoader}.
+ * This method is invoked only as a step during the loading process, which is continuing
+ * after this method invocation.
+ *
+ * @param coverage the new coverage, or {@code null} if loading failed.
+ */
+ final void onLoadStep(final GridCoverage coverage) {
+ final ObservableList<SampleDimension> items = sampleDimensions.getItems();
+ if (coverage != null) {
+ items.setAll(coverage.getSampleDimensions());
+ } else {
+ items.clear();
+ }
+ }
+
+ /**
+ * A row in the list of sample dimensions.
+ */
+ private static final class SampleDimensionCell extends ListCell<SampleDimension> {
+ /** Invoked by lambda function (needs this exact signature). */
+ SampleDimensionCell(final ListView<SampleDimension> list) {
+ }
+
+ /** Invoked when a new sample dimension needs to be shown. */
+ @Override public void updateItem(final SampleDimension item, final boolean empty) {
+ super.updateItem(item, empty);
+ setText(empty ? "" : item.getName().toString());
+ }
+ }
}
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/GridView.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/GridView.java
index 0e14c1d..e9cec04 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/GridView.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/GridView.java
@@ -254,8 +254,8 @@ public class GridView extends Control {
tileHeight = 1; // For avoiding division by zero.
setMinSize(120, 40); // 2 cells on each dimension.
- imageProperty.addListener(this::imageDefined);
- bandProperty .addListener(this::bandDefined);
+ imageProperty.addListener(this::onImageSpecified);
+ bandProperty .addListener(this::onBandSpecified);
// Other listeners registered by GridViewSkin.Flow.
}
@@ -352,8 +352,8 @@ public class GridView extends Control {
* @param image the new image to show. May be {@code null}.
* @throws ArithmeticException if the "tile grid x/y offset" property is too large.
*/
- private void imageDefined(final ObservableValue<? extends RenderedImage> property,
- final RenderedImage previous, final RenderedImage image)
+ private void onImageSpecified(final ObservableValue<? extends RenderedImage> property,
+ final RenderedImage previous, final RenderedImage image)
{
if (loader != null) {
loader.cancel();
@@ -396,8 +396,8 @@ public class GridView extends Control {
* @param previous the previous band index (ignored).
* @param band index of the new band to show.
*/
- private void bandDefined(final ObservableValue<? extends Number> property,
- final Number previous, final Number band)
+ private void onBandSpecified(final ObservableValue<? extends Number> property,
+ final Number previous, final Number band)
{
configureCellFormat(getImage(), band.intValue());
contentChanged(false);
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/ImageLoader.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/ImageLoader.java
index 69b6dfa..eb3ff25 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/ImageLoader.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/ImageLoader.java
@@ -17,6 +17,7 @@
package org.apache.sis.gui.coverage;
import java.awt.image.RenderedImage;
+import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.event.EventHandler;
import org.apache.sis.coverage.grid.GridCoverage;
@@ -117,6 +118,7 @@ final class ImageLoader extends Task<RenderedImage> {
cv = request.resource.read(domain, range); // May be long to execute.
cv = cv.forConvertedValues(converted);
request.coverage = cv;
+ Platform.runLater(request::notifyLoaded);
}
if (isCancelled()) {
return null;
@@ -133,11 +135,12 @@ final class ImageLoader extends Task<RenderedImage> {
/**
* Invoked in JavaFX thread on failure.
- * This method popups a dialog box for reporting the error.
+ * Current implementation popups a dialog box for reporting the error.
*/
@Override
protected void failed() {
super.failed();
+ request.notifyListeners(null);
final GridCoverageResource resource = request.resource;
if (resource instanceof StoreListeners) {
ExceptionReporter.canNotReadFile(((StoreListeners) resource).getSourceName(), getException());
@@ -145,4 +148,13 @@ final class ImageLoader extends Task<RenderedImage> {
ExceptionReporter.canNotUseResource(getException());
}
}
+
+ /**
+ * Invoked in JavaFX thread in case of cancellation.
+ */
+ @Override
+ protected void cancelled() {
+ super.cancelled();
+ request.notifyListeners(null);
+ }
}
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/ImageRequest.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/ImageRequest.java
index 3f32f09..b766222 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/ImageRequest.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/ImageRequest.java
@@ -16,6 +16,7 @@
*/
package org.apache.sis.gui.coverage;
+import java.util.Arrays;
import java.util.Optional;
import java.util.OptionalInt;
import org.apache.sis.storage.GridCoverageResource;
@@ -90,6 +91,15 @@ public class ImageRequest {
private int overviewSize;
/**
+ * The coverage explorers to inform when {@link #coverage} become available, or {@code null} if none.
+ * We do not provide a more generic listeners API for now, but it could be done in the future if there
+ * is a need for that.
+ *
+ * @see #addListener(CoverageExplorer)
+ */
+ private CoverageExplorer[] listeners;
+
+ /**
* Creates a new request for loading an image from the specified resource.
* If {@code domain} and {@code range} arguments are null, then the full coverage will be loaded.
* For loading a smaller amount of data, sub-domain or sub-range can be specified as documented
@@ -238,4 +248,44 @@ public class ImageRequest {
ArgumentChecks.ensureStrictlyPositive("size", size);
overviewSize = size;
}
+
+ /**
+ * Adds a listener to inform when {@link #coverage} become available. We do not provide a more
+ * generic listeners API for now, but it could be done in the future if there is a need for that.
+ *
+ * <p>All listeners are discarded after the reading process.</p>
+ */
+ final void addListener(final CoverageExplorer listener) {
+ final int n;
+ if (listeners == null) { // Usual case.
+ n = 0;
+ listeners = new CoverageExplorer[1];
+ } else { // Should be very rare.
+ n = listeners.length;
+ listeners = Arrays.copyOf(listeners, n+1);
+ }
+ listeners[n] = listener;
+ }
+
+ /**
+ * Notifies all listeners that the given coverage has been read or failed to be read,
+ * then discards the listeners. This method shall be invoked in JavaFX thread.
+ *
+ * @param result the result, or {@code null} on failure.
+ */
+ final void notifyListeners(final GridCoverage result) {
+ final CoverageExplorer[] snapshot = listeners;
+ listeners = null; // Clear now in case an error happen.
+ for (final CoverageExplorer e : snapshot) {
+ e.onLoadStep(result);
+ }
+ }
+
+ /**
+ * Notifies all listeners that the coverage has been read, then discards the listeners.
+ * This method shall be invoked in JavaFX thread.
+ */
+ final void notifyLoaded() {
+ notifyListeners(coverage);
+ }
}
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/ExceptionReporter.java b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/ExceptionReporter.java
index b11d1ca..8e0c617 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/ExceptionReporter.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/ExceptionReporter.java
@@ -21,13 +21,13 @@ import java.io.StringWriter;
import javafx.concurrent.Worker;
import javafx.concurrent.WorkerStateEvent;
import javafx.event.ActionEvent;
-import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Alert;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.DialogPane;
import javafx.scene.control.Label;
+import javafx.scene.control.Menu;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import javafx.scene.layout.Region;
@@ -47,13 +47,18 @@ import org.apache.sis.util.Classes;
* @since 1.1
* @module
*/
-public final class ExceptionReporter implements EventHandler<ActionEvent> {
+public final class ExceptionReporter {
/**
* The margin to use for the stack trace. We add some spaces on the top and left sides.
*/
private static final Insets MARGIN = new Insets(9, 0, 0, 40);
/**
+ * The exception that occurred.
+ */
+ private final Throwable exception;
+
+ /**
* The component where to show the stack trace.
*/
private final Label trace;
@@ -63,14 +68,17 @@ public final class ExceptionReporter implements EventHandler<ActionEvent> {
*
* @param exception the error to report.
*/
+ @SuppressWarnings("ThisEscapedInObjectConstruction")
public ExceptionReporter(final Throwable exception) {
+ this.exception = exception;
trace = new Label(getStackTrace(exception));
trace.setAlignment(Pos.TOP_LEFT);
trace.setPadding(MARGIN);
final Resources localized = Resources.getInstance();
- final ContextMenu menu = new ContextMenu();
- menu.getItems().add(localized.menu(Resources.Keys.Copy, this));
+ final Menu sendTo = new Menu(localized.getString(Resources.Keys.SendTo));
+ sendTo.getItems().add(localized.menu(Resources.Keys.StandardErrorStream, this::printStackTrace));
+ final ContextMenu menu = new ContextMenu(localized.menu(Resources.Keys.Copy, this::copy), sendTo);
trace.setContextMenu(menu);
}
@@ -205,14 +213,22 @@ public final class ExceptionReporter implements EventHandler<ActionEvent> {
/**
* Invoked when the user selected the "Copy" action in contextual menu.
- * This method is public as an implementation side-effect; do not use.
*
* @param event ignored.
*/
- @Override
- public void handle(final ActionEvent event) {
+ private void copy(final ActionEvent event) {
final ClipboardContent content = new ClipboardContent();
content.putString(trace.getText());
Clipboard.getSystemClipboard().setContent(content);
}
+
+ /**
+ * Invoked when the user selected the "Send to ⏵ Standard error stream" action in contextual menu.
+ *
+ * @param event ignored.
+ */
+ @SuppressWarnings("CallToPrintStackTrace")
+ private void printStackTrace(final ActionEvent event) {
+ exception.printStackTrace();
+ }
}
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/Resources.java b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/Resources.java
index f5e3199..782474b 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/Resources.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/Resources.java
@@ -271,11 +271,21 @@ public final class Resources extends IndexedResourceBundle {
public static final short SelectCRS = 37;
/**
+ * Send to
+ */
+ public static final short SendTo = 49;
+
+ /**
* Spatial representation
*/
public static final short SpatialRepresentation = 24;
/**
+ * Standard error stream
+ */
+ public static final short StandardErrorStream = 50;
+
+ /**
* Summary
*/
public static final short Summary = 29;
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/Resources.properties b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/Resources.properties
index 8328640..581194d 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/Resources.properties
+++ b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/Resources.properties
@@ -64,6 +64,8 @@ ReferenceSystem = Reference system:
ResourceIdentification = Resource identification
SpatialRepresentation = Spatial representation
SelectCRS = Select a coordinate reference system
+SendTo = Send to
+StandardErrorStream = Standard error stream
Summary = Summary
TopicCategory = Topic category:
TypeOfResource = Type of resource:
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/Resources_fr.properties b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/Resources_fr.properties
index a23fb87..de60cb6 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/Resources_fr.properties
+++ b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/Resources_fr.properties
@@ -69,6 +69,8 @@ ReferenceSystem = Syst\u00e8me de r\u00e9f\u00e9rence\u00a0:
ResourceIdentification = Identification de la ressource
SpatialRepresentation = Repr\u00e9sentation spatiale
SelectCRS = Choisir un syst\u00e8me de r\u00e9f\u00e9rence des coordonn\u00e9es
+SendTo = Envoyer vers
+StandardErrorStream = Flux d\u2019erreur standard
Summary = R\u00e9sum\u00e9
TopicCategory = Cat\u00e9gorie th\u00e9matique\u00a0:
TypeOfResource = Type de ressource\u00a0:
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
index 94f8285..9f3d6c0 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
@@ -210,6 +210,11 @@ public final class Vocabulary extends IndexedResourceBundle {
public static final short Correlation = 28;
/**
+ * Coverage
+ */
+ public static final short Coverage = 190;
+
+ /**
* Coverage domain
*/
public static final short CoverageDomain = 29;
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
index 6d2e80a..f605ae9 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
@@ -45,6 +45,7 @@ Conversion = Conversion
Coordinate = Coordinate
CoordinateRefSys = Coordinate reference system
Correlation = Correlation
+Coverage = Coverage
CoverageDomain = Coverage domain
Create = Create
CurrentDateTime = Current date and time
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
index bc1779e..f10f4f1 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
@@ -52,6 +52,7 @@ Conversion = Conversion
Coordinate = Coordonn\u00e9e
CoordinateRefSys = Syst\u00e8me de r\u00e9f\u00e9rence des coordonn\u00e9es
Correlation = Corr\u00e9lation
+Coverage = Couverture de donn\u00e9es
CoverageDomain = Domaine de la couverture de donn\u00e9es
Create = Cr\u00e9ation
CurrentDateTime = Date et heure courantes