sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 03/04: Provides an indication that work is in progress and report error in the status bar.
Date Mon, 02 Mar 2020 19:33:17 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 a12613609d48b964df77661e643ddea72fb346d1
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Mon Mar 2 19:56:59 2020 +0100

    Provides an indication that work is in progress and report error in the status bar.
---
 .../org/apache/sis/gui/coverage/CoverageView.java  | 31 ++++++++----
 .../org/apache/sis/gui/coverage/StatusBar.java     | 57 +++++++++++++++++++---
 2 files changed, 72 insertions(+), 16 deletions(-)

diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageView.java
b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageView.java
index 3f54ac3..5f3fd48 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageView.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageView.java
@@ -51,7 +51,6 @@ import org.apache.sis.coverage.grid.GridExtent;
 import org.apache.sis.coverage.grid.GridGeometry;
 import org.apache.sis.internal.coverage.j2d.ColorModelFactory;
 import org.apache.sis.internal.gui.BackgroundThreads;
-import org.apache.sis.internal.gui.ExceptionReporter;
 import org.apache.sis.internal.gui.ImageRenderings;
 import org.apache.sis.internal.map.PlanarCanvas;
 import org.apache.sis.internal.util.Numerics;
@@ -174,6 +173,7 @@ final class CoverageView extends PlanarCanvas {
      * Incremented when {@link #data} or {@link #dataToImage} changed.
      *
      * @see #renderedDataStamp
+     * @see #isDataChanged()
      */
     private int dataChangeCount;
 
@@ -181,7 +181,7 @@ final class CoverageView extends PlanarCanvas {
      * Value of {@link #dataChangeCount} last time the data have been rendered. This is used
for deciding
      * if a call to {@link #repaint()} should be done with the next layout operation. We
need this check
      * for avoiding never-ending repaint events caused by calls to {@link ImageView#setImage(Image)}
-     * causing themselves new layout events.
+     * causing themselves new layout events. It is okay if this value overflows.
      */
     private int renderedDataStamp;
 
@@ -203,7 +203,9 @@ final class CoverageView extends PlanarCanvas {
         imageRegion = new Pane() {
             @Override protected void layoutChildren() {
                 super.layoutChildren();
-                repaint();
+                if (isDataChanged()) {
+                    repaint();
+                }
             }
         };
         image = new ImageView();
@@ -301,7 +303,8 @@ final class CoverageView extends PlanarCanvas {
      * But {@link Task#succeeded()} and similar methods can read and write those fields.</p>
      */
     private void execute(final Task<?> task) {
-        // TODO: set a listener on task.state property.
+        statusBar.setErrorMessage(null);
+        task.runningProperty().addListener(statusBar::setRunningState);
         task.setOnFailed((e) -> errorOccurred(e.getSource().getException()));
         BackgroundThreads.execute(task);
     }
@@ -392,7 +395,7 @@ final class CoverageView extends PlanarCanvas {
          */
         dataAlternatives.put(type, alt);
         alt = dataAlternatives.get(currentDataAlternative);
-        if (alt != data) {
+        if (!Objects.equals(alt, data)) {
             data = alt;
             dataChangeCount++;
             imageRegion.requestLayout();
@@ -407,14 +410,18 @@ final class CoverageView extends PlanarCanvas {
     }
 
     /**
+     * Returns {@code true} if data changed since the last {@link #repaint()} execution.
+     */
+    private boolean isDataChanged() {
+        return dataChangeCount != renderedDataStamp;
+    }
+
+    /**
      * Invoked when the {@link #data} content needs to be rendered again into {@link #image}.
      * It may be because a new image has been specified, or because the viewed region moved
      * or have been zoomed.
      */
     private void repaint() {
-        if (dataChangeCount == renderedDataStamp) {
-            return;                                 // Nothing changed since last rendering.
-        }
         renderedDataStamp = dataChangeCount;
         final RenderedImage data = this.data;       // Need to copy this reference here before
background tasks.
         if (data == null) {
@@ -594,10 +601,14 @@ final class CoverageView extends PlanarCanvas {
      *
      * @param  ex  the exception that occurred.
      *
-     * @todo should do something better (e.g. show in status bar).
+     * @todo Should provide a button for getting more details.
      */
     private void errorOccurred(final Throwable ex) {
-        ExceptionReporter.show(null, null, ex);
+        String message = ex.getMessage();
+        if (message == null) {
+            message = ex.toString();
+        }
+        statusBar.setErrorMessage(message);
     }
 
     /**
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/StatusBar.java
b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/StatusBar.java
index f7e92d0..9de29ed 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/StatusBar.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/StatusBar.java
@@ -20,12 +20,15 @@ import java.util.Locale;
 import java.util.function.Consumer;
 import javax.measure.Unit;
 import javafx.geometry.Insets;
-import javafx.geometry.Pos;
+import javafx.scene.paint.Color;
 import javafx.scene.layout.HBox;
+import javafx.scene.layout.Priority;
 import javafx.scene.control.Label;
 import javafx.scene.control.Tooltip;
+import javafx.scene.control.ProgressBar;
 import javafx.scene.input.MouseEvent;
 import javafx.event.EventHandler;
+import javafx.beans.value.ObservableValue;
 import org.opengis.referencing.datum.PixelInCell;
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.operation.Matrix;
@@ -49,7 +52,7 @@ import org.apache.sis.util.Exceptions;
  *
  * <p>Callers can register this object to {@link javafx.scene.Node#setOnMouseEntered(EventHandler)}
and
  * {@link javafx.scene.Node#setOnMouseExited(EventHandler)} for showing or hiding the coordinate
values
- * when the mouse enter or exit the region of interest.</p>
+ * when the mouse enters or exits the region of interest.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @version 1.1
@@ -58,6 +61,23 @@ import org.apache.sis.util.Exceptions;
  */
 final class StatusBar extends HBox implements EventHandler<MouseEvent> {
     /**
+     * Some spaces to add around the status bar.
+     */
+    private static final Insets PADDING = new Insets(5, GridViewSkin.SCROLLBAR_WIDTH, 6,
0);
+
+    /**
+     * The progress bar, hidden by default. This bar is initialized to undetermined state.
+     */
+    private final ProgressBar progress;
+
+    /**
+     * Message to write in the middle of the status bar.
+     * This component usually has nothing to show; it is used mostly for error messages.
+     * It takes all the space between {@link #progress} and {@link #coordinates}.
+     */
+    private final Label message;
+
+    /**
      * A function which take cell indices in input and gives pixel coordinates in output.
      * The input and output coordinates are in the given array, which is updated in-place.
      *
@@ -110,11 +130,20 @@ final class StatusBar extends HBox implements EventHandler<MouseEvent>
{
      */
     StatusBar(final Consumer<double[]> toImageCoordinates) {
         this.toImageCoordinates = toImageCoordinates;
-        format = new CoordinateFormat();
+        format      = new CoordinateFormat();
         coordinates = new Label();
-        setAlignment(Pos.CENTER_RIGHT);
-        getChildren().setAll(coordinates);
-        setPadding(new Insets(5, GridViewSkin.SCROLLBAR_WIDTH, 6, 0));
+        message     = new Label();
+        progress    = new ProgressBar();
+        progress.setVisible(false);
+        message.setTextFill(Color.RED);
+        message.setMaxWidth(Double.POSITIVE_INFINITY);
+        HBox.setHgrow(message, Priority.ALWAYS);
+        getChildren().setAll(progress, message, coordinates);
+        setPadding(PADDING);
+        setSpacing(12);
+        /*
+         * Following method call will initialize `gridtoCRS` to default value.
+         */
         setCoordinateConversion(null, null);
     }
 
@@ -266,4 +295,20 @@ final class StatusBar extends HBox implements EventHandler<MouseEvent>
{
     public final void handle(final MouseEvent event) {
         coordinates.setVisible(event != null && event.getEventType() != MouseEvent.MOUSE_EXITED);
     }
+
+    /**
+     * Invoked when the {@link javafx.concurrent.Worker#runningProperty()} state of a task
changed.
+     * This method shows or hides the progress bar according the {@code newValue} argument.
+     */
+    final void setRunningState(ObservableValue<? extends Boolean> property, Boolean
oldValue, Boolean newValue) {
+        progress.setVisible(newValue);
+    }
+
+    /**
+     * Invoked when an error occurred, or for clearing the error message.
+     */
+    final void setErrorMessage(final String text) {
+        message.setVisible(text != null);
+        message.setText(text);
+    }
 }


Mime
View raw message