sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 05/06: Fix problem with metadata panel not always updated correctly with new content.
Date Wed, 15 Jul 2020 18:06:03 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 84caa42199b0fb3f6c8fb9c1342809dc53565aa5
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Wed Jul 15 13:11:19 2020 +0200

    Fix problem with metadata panel not always updated correctly with new content.
---
 .../org/apache/sis/gui/dataset/ResourceTree.java   | 15 ++++
 .../sis/gui/metadata/IdentificationInfo.java       | 10 ++-
 .../apache/sis/gui/metadata/MetadataSummary.java   | 96 ++++++++++++++--------
 3 files changed, 87 insertions(+), 34 deletions(-)

diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ResourceTree.java
b/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ResourceTree.java
index 6cb076a..7faba4f 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ResourceTree.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ResourceTree.java
@@ -276,6 +276,21 @@ public class ResourceTree extends TreeView<Resource> {
     private boolean findOrRemove(final Resource resource, final boolean remove) {
         assert Platform.isFxApplicationThread();
         if (resource != null) {
+            /*
+             * If the item to remove is selected, unselect it before to remove it.
+             * The `ResourceExplorer` will be notified by a change event.
+             */
+            if (remove) {
+                final ObservableList<TreeItem<Resource>> items = getSelectionModel().getSelectedItems();
+                for (int i=items.size(); --i >= 0;) {
+                    if (items.get(i).getValue() == resource) {
+                        getSelectionModel().clearSelection(i);
+                    }
+                }
+            }
+            /*
+             * Search for the resource from the root, and optionally remove it.
+             */
             final TreeItem<Resource> item = getRoot();
             if (item != null) {
                 final Resource root = item.getValue();
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/IdentificationInfo.java
b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/IdentificationInfo.java
index 0dfe761..1c83184 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/IdentificationInfo.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/IdentificationInfo.java
@@ -18,6 +18,7 @@ package org.apache.sis.gui.metadata;
 
 import java.util.Date;
 import java.util.Set;
+import java.util.Collection;
 import java.util.LinkedHashSet;
 import java.util.StringJoiner;
 import javafx.concurrent.Task;
@@ -240,7 +241,14 @@ final class IdentificationInfo extends Section<Identification>
{
             aggregateWalker.cancel();
             aggregateWalker = null;
         }
-        setInformation(nonNull(metadata == null ? null : metadata.getIdentificationInfo()),
Identification[]::new);
+        final Collection<? extends Identification> info;
+        if (metadata == null) {
+            clearWorldMap();
+            info = null;
+        } else {
+            info = metadata.getIdentificationInfo();
+        }
+        setInformation(nonNull(info), Identification[]::new);
     }
 
     /**
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataSummary.java
b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataSummary.java
index ef94a91..f5ccfa9 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataSummary.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataSummary.java
@@ -29,7 +29,6 @@ import javafx.beans.property.SimpleObjectProperty;
 import javafx.beans.value.ObservableValue;
 import javafx.collections.ObservableList;
 import javafx.concurrent.Task;
-import javafx.concurrent.Worker;
 import javafx.scene.Node;
 import javafx.scene.control.ScrollPane;
 import javafx.scene.control.TitledPane;
@@ -106,10 +105,10 @@ public class MetadataSummary extends Widget {
 
     /**
      * If this {@link MetadataSummary} is loading metadata, the worker doing this task.
-     * Otherwise {@code null}. This is used for cancelling the currently running loading
+     * Otherwise {@code null}. This is used for cancelling the currently running getter
      * process if {@link #setMetadata(Resource)} is invoked again before completion.
      */
-    private Worker<Metadata> loader;
+    private Getter getter;
 
     /**
      * The metadata shown in this pane.
@@ -152,9 +151,9 @@ public class MetadataSummary extends Widget {
         };
         content = new ScrollPane(new VBox());
         content.setFitToWidth(true);
+        nativeMetadataViews = new ArrayList<>();
         metadataProperty = new SimpleObjectProperty<>(this, "metadata");
         metadataProperty.addListener(MetadataSummary::applyChange);
-        nativeMetadataViews = new ArrayList<>();
     }
 
     /**
@@ -211,42 +210,62 @@ public class MetadataSummary extends Widget {
      */
     public void setMetadata(final Resource resource) {
         assert Platform.isFxApplicationThread();
-        if (loader != null) {
-            loader.cancel();
-            loader = null;
+        if (getter != null) {
+            getter.cancel();
+            getter = null;
         }
         if (resource == null) {
             setMetadata((Metadata) null);
         } else {
-            final class Getter extends Task<Metadata> {
-                /** The native metadata, or {@code null} if none or not requested. */
-                private TreeTable nativeMetadata;
-
-                /** Invoked in a background thread for fetching metadata. */
-                @Override protected Metadata call() throws DataStoreException {
-                    if (resource instanceof DataStore && !nativeMetadataViews.isEmpty())
{
-                        nativeMetadata = ((DataStore) resource).getNativeMetadata().orElse(null);
-                    }
-                    return resource.getMetadata();
-                }
+            BackgroundThreads.execute(getter = new Getter(resource));
+        }
+    }
 
-                /** Shows the result in JavaFX thread. */
-                @Override protected void succeeded() {
-                    setMetadata(getValue());
-                    for (final MetadataTree view : nativeMetadataViews) {
-                        view.setContent(nativeMetadata);
-                    }
-                    if (resource instanceof Aggregate) {
-                        getIdentificationInfo().completeMissingGeographicBounds((Aggregate)
resource);
-                    }
-                }
+    /**
+     * The task getting metadata in a background thread. The call to {@link Resource#getMetadata()}
is
+     * instantaneous with some resource implementations, but other implementations may have
deferred
+     * metadata construction until first requested.
+     */
+    private final class Getter extends Task<Metadata> {
+        /** The resource from which to load metadata. */
+        private final Resource resource;
+
+        /** The native metadata, or {@code null} if none or not requested. */
+        TreeTable nativeMetadata;
 
-                /** Invoked in JavaFX thread if metadata loading failed. */
-                @Override protected void failed() {
-                    setError(getException());
+        /** Creates a new metadata getter. */
+        Getter(final Resource resource) {
+            this.resource = resource;
+        }
+
+        /** Invoked in a background thread for fetching metadata. */
+        @Override protected Metadata call() throws DataStoreException {
+            if (resource instanceof DataStore && !nativeMetadataViews.isEmpty())
{
+                nativeMetadata = ((DataStore) resource).getNativeMetadata().orElse(null);
+            }
+            return resource.getMetadata();
+        }
+
+        /** Shows the result in JavaFX thread. */
+        @Override protected void succeeded() {
+            if (getter == this) try {
+                setMetadata(getValue());
+                if (resource instanceof Aggregate) {
+                    getIdentificationInfo().completeMissingGeographicBounds((Aggregate) resource);
                 }
+            } finally {
+                getter = null;
+            }
+        }
+
+        /* No need to override `canceled()` because `getter` is cleared at `cancel()` invocation
time. */
+
+        /** Invoked in JavaFX thread if metadata loading failed. */
+        @Override protected void failed() {
+            if (getter == this) {
+                getter = null;
+                setError(getException());
             }
-            BackgroundThreads.execute(new Getter());
         }
     }
 
@@ -305,8 +324,19 @@ public class MetadataSummary extends Widget {
                                     final Metadata oldValue, final Metadata metadata)
     {
         final MetadataSummary s = (MetadataSummary) ((SimpleObjectProperty<?>) property).getBean();
-        s.error = null;
+        final Getter getter = s.getter;
+        s.getter = null;                // In case this method is invoked before `Getter`
completed.
+        s.error  = null;
         if (metadata != oldValue) {
+            /*
+             * The native metadata are handled in a special way by `setMetadata(Resource)`.
+             * Since we have no public API for setting native metadata in `MetadataSummary`,
+             * we set the value to null if this method is not invoked from `Getter.succeeded()`.
+             */
+            final TreeTable nativeMetadata = (getter != null && getter.isDone())
? getter.nativeMetadata : null;
+            for (final MetadataTree view : s.nativeMetadataViews) {
+                view.setContent(nativeMetadata);
+            }
             final ObservableList<Node> children = s.getChildren();
             if (!children.isEmpty() && !(children.get(0) instanceof Section)) {
                 children.clear();       // If we were previously showing an error, clear
all.


Mime
View raw message