sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 02/02: Copy Smaniotto Enzo's work from https://issues.apache.org/jira/browse/SIS-417. This work will need major review and cleanup for exception handlings, factorization, etc. This cleanup is deferred to a later time.
Date Tue, 03 Jul 2018 13:39:24 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 22e093004f0e406b9011a14ff0c3ef0517b51cb2
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Tue Jul 3 12:21:46 2018 +0200

    Copy Smaniotto Enzo's work from https://issues.apache.org/jira/browse/SIS-417.
    This work will need major review and cleanup for exception handlings, factorization, etc.
    This cleanup is deferred to a later time.
---
 .../org/apache/sis/gui/dataset/FeatureTable.java   | 169 +++++++++++++++++
 .../org/apache/sis/gui/dataset/ResourceTree.java   |  23 +--
 .../apache/sis/gui/metadata/MetadataOverview.java  | 120 ++++++------
 .../org/apache/sis/gui/metadata/ResourceView.java  | 207 +++++++++++++++------
 .../apache/sis/gui/metadata/WorldMap360x180.png    | Bin 0 -> 1886 bytes
 5 files changed, 385 insertions(+), 134 deletions(-)

diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/FeatureTable.java
b/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/FeatureTable.java
new file mode 100644
index 0000000..fa5338a
--- /dev/null
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/FeatureTable.java
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.gui.dataset;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Iterator;
+import java.util.ResourceBundle;
+import java.util.MissingResourceException;
+import java.util.stream.Stream;
+import java.util.stream.Collectors;
+import javafx.collections.FXCollections;
+import javafx.scene.control.Label;
+import javafx.scene.control.ScrollPane;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableView;
+import javafx.scene.control.TreeItem;
+import javafx.scene.control.TreeView;
+import javafx.scene.layout.BorderPane;
+import javafx.beans.property.SimpleObjectProperty;
+import org.opengis.feature.Feature;
+import org.opengis.feature.PropertyType;
+import org.opengis.geometry.Geometry;
+import org.apache.sis.internal.util.CheckedArrayList;
+import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.storage.FeatureSet;
+import org.apache.sis.storage.Resource;
+
+
+/**
+ *
+ * @author  Johann Sorel (Geomatys)
+ * @author  Smaniotto Enzo
+ * @version 1.0
+ * @since   1.0
+ * @module
+ */
+public class FeatureTable extends BorderPane {
+    /**
+     * Contains ResourceBundles indexed by table names.
+     */
+    private final Map<String, ResourceBundle> bundles = new HashMap<>();
+
+    private String bundlePrefix;
+
+    private String generateFinalColumnName(final PropertyType prop) {
+        Map<String, Map.Entry<String, String>> labelInfo = (Map) prop.getDesignation();
+        final String labelName = prop.getName().toString();
+        String columnName = labelName;
+        String tableName = null;
+        /*
+         * If exists, explore labelInfo to retrive table and column respect to this label.
+         */
+        if (labelInfo != null) {
+            final Map.Entry<String, String> entry = labelInfo.get(labelName);
+            if (entry != null) {
+                if (entry.getKey() != null) {
+                    tableName = entry.getKey();
+                } else {
+                    tableName = null;
+                }
+                if (entry.getValue() != null) {
+                    columnName = entry.getValue();
+                } else {
+                    columnName = labelName;
+                }
+            }
+        }
+        /*
+         * If table name is not null, try to found resourcebundle for this table.
+         */
+        if (tableName != null) {
+            /*
+             * If there isn't resource bundles (or not for the curruen table), try to generate.
+             */
+            if (bundles.get(tableName) == null) {
+                if (bundlePrefix != null) {
+                    bundles.put(tableName, ResourceBundle.getBundle(bundlePrefix + tableName));
+                }
+            }
+        }
+        final ResourceBundle bundle = bundles.get(tableName);
+        String finalColumnName;
+        if (labelName == null) {
+            finalColumnName = "";
+        } else if (bundle == null) {
+            if (!labelName.equals(columnName)) {
+                finalColumnName = columnName + " as " + labelName;
+            } else {
+                finalColumnName = columnName;
+            }
+        } else {
+            try {
+                if (!labelName.equals(columnName)) {
+                    finalColumnName = bundle.getString(columnName) + " as " + labelName;
+                } else {
+                    finalColumnName = bundle.getString(columnName);
+                }
+            } catch (MissingResourceException ex) {
+                if (!labelName.equals(columnName)) {
+                    finalColumnName = columnName + " as " + labelName;
+                } else {
+                    finalColumnName = columnName;
+                }
+            }
+        }
+        return finalColumnName;
+    }
+
+    public FeatureTable(Resource res, int i) throws DataStoreException {
+        TableView<Feature> ttv = new TableView<>();
+        final ScrollPane scroll = new ScrollPane(ttv);
+        scroll.setFitToHeight(true);
+        scroll.setFitToWidth(true);
+        ttv.setColumnResizePolicy(TableView.UNCONSTRAINED_RESIZE_POLICY);
+        ttv.setTableMenuButtonVisible(true);
+        ttv.setFixedCellSize(100);
+        scroll.setPrefSize(600, 400);
+        scroll.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
+        setCenter(scroll);
+        final List<Feature> list;
+        if (res instanceof FeatureSet) {
+            try (Stream<Feature> stream = ((FeatureSet) res).features(false)) {
+                list = stream.collect(Collectors.toList());
+                ttv.setItems(FXCollections.observableArrayList(list));
+                for (PropertyType pt : list.get(0).getType().getProperties(false)) {
+                    final TableColumn<Feature, BorderPane> column = new TableColumn<>(generateFinalColumnName(pt));
+                    column.setCellValueFactory((TableColumn.CellDataFeatures<Feature,
BorderPane> param) -> {
+                        final Object val = param.getValue().getPropertyValue(pt.getName().toString());
+                        if (val instanceof Geometry) {
+                            return new SimpleObjectProperty<>(new BorderPane(new Label("{geometry}")));
+                        } else {
+                            SimpleObjectProperty<BorderPane> sop = new SimpleObjectProperty<>();
+                            if (val instanceof CheckedArrayList<?>) {
+                                Iterator<String> it = ((CheckedArrayList<String>)
val).iterator();
+                                TreeItem<String> ti = new TreeItem<>(it.next());
+                                while (it.hasNext()) {
+                                    ti.getChildren().add(new TreeItem<>(it.next()));
+                                }
+                                BorderPane bp = new BorderPane(new TreeView<>(ti));
+                                sop.setValue(bp);
+                                return sop;
+                            } else {
+                                sop.setValue(new BorderPane(new Label(String.valueOf(val))));
+                                return sop;
+                            }
+                        }
+                    });
+                    ttv.getColumns().add(column);
+                }
+            }
+        }
+    }
+}
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 c892e95..e45df06 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
@@ -51,9 +51,9 @@ import org.opengis.util.InternationalString;
 /**
  * Tree viewer displaying a {@link Resource} hierarchy.
  *
- * @author Johann Sorel (Geomatys)
- * @version 0.8
- * @since   0.8
+ * @author  Johann Sorel (Geomatys)
+ * @version 1.0
+ * @since   1.0
  * @module
  */
 public class ResourceTree extends TreeTableView<Resource> {
@@ -75,7 +75,7 @@ public class ResourceTree extends TreeTableView<Resource> {
      */
     public Resource getResource() {
         final TreeItem<Resource> root = getRoot();
-        return root==null ? null : root.getValue();
+        return root == null ? null : root.getValue();
     }
 
     /**
@@ -84,7 +84,7 @@ public class ResourceTree extends TreeTableView<Resource> {
      * @param resource can be null
      */
     public void setResource(Resource resource) {
-        if (resource==null) {
+        if (resource == null) {
             setRoot(null);
         } else {
             setRoot(new ResourceItem(resource));
@@ -95,7 +95,7 @@ public class ResourceTree extends TreeTableView<Resource> {
      * Find an appropriate icon for given resource.
      *
      * @param resource resource to test
-     * @return Image icon
+     * @return image icon
      */
     private static Image getTypeIcon(Resource resource){
         if (resource instanceof FeatureSet) {
@@ -105,7 +105,7 @@ public class ResourceTree extends TreeTableView<Resource> {
         } else if (resource instanceof Aggregate) {
             return ICON_FOLDER;
         } else {
-            //unspecific resource type
+            // Unspecific resource type
             return ICON_OTHER;
         }
     }
@@ -183,13 +183,12 @@ public class ResourceTree extends TreeTableView<Resource> {
                         lst.add(new ResourceItem(res));
                     }
                 } catch (DataStoreException ex) {
-                    ex.printStackTrace();
+                    ex.printStackTrace();                   // TODO: need better handling.
                 }
                 return lst;
             }
-            return Collections.EMPTY_LIST;
+            return Collections.emptyList();
         }
-
     }
 
     private static class ResourceNameColumn extends TreeTableColumn<Resource,String>
{
@@ -204,7 +203,7 @@ public class ResourceTree extends TreeTableView<Resource> {
                     try {
                         return new SimpleObjectProperty<>(getTitle(name, res.getMetadata()));
                     } catch (DataStoreException ex) {
-                       return new SimpleObjectProperty<>(ex.getMessage());
+                        return new SimpleObjectProperty<>(ex.getMessage());
                     }
                 }
             });
@@ -214,7 +213,6 @@ public class ResourceTree extends TreeTableView<Resource> {
             setMinWidth(120);
             setResizable(true);
         }
-
     }
 
     private static class Cell extends TreeTableCell<Resource, String> {
@@ -238,7 +236,6 @@ public class ResourceTree extends TreeTableView<Resource> {
             if (ti == null) {
                 return;
             }
-
             final Resource resource = ti.getValue();
             setGraphic(new ImageView(getTypeIcon(resource)));
         }
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataOverview.java
b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataOverview.java
index 594a59d..90f5e4c 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataOverview.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataOverview.java
@@ -16,21 +16,19 @@
  */
 package org.apache.sis.gui.metadata;
 
-import java.io.File;
-import java.net.MalformedURLException;
+import java.io.IOException;
+import java.io.InputStream;
 import java.text.DateFormat;
 import java.text.NumberFormat;
-import static java.text.NumberFormat.getIntegerInstance;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Locale;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+import java.util.Map;
 import javafx.beans.value.ObservableValue;
 import javafx.collections.FXCollections;
 import javafx.collections.ObservableList;
-import static javafx.event.ActionEvent.ACTION;
+import javafx.event.ActionEvent;
 import javafx.event.Event;
 import javafx.geometry.Insets;
 import javafx.scene.Node;
@@ -48,11 +46,6 @@ import javafx.scene.layout.Priority;
 import javafx.scene.layout.StackPane;
 import javafx.scene.layout.VBox;
 import javafx.scene.paint.Color;
-import org.apache.sis.metadata.iso.DefaultMetadata;
-import org.apache.sis.metadata.iso.citation.DefaultIndividual;
-import org.apache.sis.metadata.iso.citation.DefaultOrganisation;
-import org.apache.sis.metadata.iso.spatial.DefaultGridSpatialRepresentation;
-import static org.apache.sis.util.iso.Types.getCodeTitle;
 import org.opengis.metadata.Metadata;
 import org.opengis.metadata.citation.CitationDate;
 import org.opengis.metadata.citation.Party;
@@ -69,27 +62,35 @@ import org.opengis.metadata.spatial.SpatialRepresentation;
 import org.opengis.metadata.spatial.SpatialRepresentationType;
 import org.opengis.referencing.ReferenceSystem;
 import org.opengis.util.InternationalString;
+import org.apache.sis.metadata.iso.DefaultMetadata;
+import org.apache.sis.metadata.iso.citation.DefaultIndividual;
+import org.apache.sis.metadata.iso.citation.DefaultOrganisation;
+import org.apache.sis.metadata.iso.spatial.DefaultGridSpatialRepresentation;
+import org.apache.sis.util.iso.Types;
+
 
 /**
  * Metadata Viewer.
  *
- * @author Smaniotto Enzo
+ * @author  Smaniotto Enzo
+ * @version 1.0
+ * @since   1.0
+ * @module
  */
 class MetadataOverview extends StackPane {
 
-    private final Metadata METADATA;
-    private final String FROMFILE;
-    private final Locale LOCALE = Locale.getDefault();
+    private final Metadata metadata;
+    final String fromFile;
+    private final Locale locale = Locale.getDefault();
 
-    public MetadataOverview(DefaultMetadata _md, String _fromFile) {
-        METADATA = _md;
-        FROMFILE = _fromFile;
+    public MetadataOverview(final DefaultMetadata md, final String fromFile) {
+        this.metadata = md;
+        this.fromFile = fromFile;
         VBox root = new VBox();
         root.setStyle("-fx-background-color: linear-gradient(to bottom right, #aeb7c4, #fafafa);");
 
         // Creation of the differents views.
         VBox summaryView = createSummaryView();
-        DefaultMetadata md = (DefaultMetadata) METADATA;
         MetadataNode advancedView = new MetadataNode(md.asTreeTable());
         advancedView.setMaxHeight(Double.MAX_VALUE);
         VBox.setVgrow(advancedView, Priority.ALWAYS);
@@ -133,9 +134,12 @@ class MetadataOverview extends StackPane {
     private VBox createSummaryView() {
         VBox vb = new VBox();
         TitledPane idPane = new TitledPane("Identification info", createIdGridPane());
-        TitledPane spatialPane = new TitledPane("Spatial representation", createSpatialGridPane());
+        GridPane createSpatialGridPane = createSpatialGridPane();
         vb.getChildren().add(idPane);
-        vb.getChildren().add(spatialPane);
+        if (!createSpatialGridPane.getChildren().isEmpty()) {
+            TitledPane spatialPane = new TitledPane("Spatial representation", createSpatialGridPane);
+            vb.getChildren().add(spatialPane);
+        }
         return vb;
     }
 
@@ -145,10 +149,10 @@ class MetadataOverview extends StackPane {
         int j = 0, k = 1;
 
         HashMap<String, Identification> m = new HashMap<>();
-        ComboBox comboBox = createComboBox(m);
+        ComboBox<String> comboBox = createComboBox(m);
         comboBox.setStyle("-fx-font-weight: bold; -fx-font-size: 2em;");
         if (!comboBox.isVisible()) {
-            Label la = new Label(comboBox.getValue().toString());
+            Label la = new Label(comboBox.getValue());
             la.setStyle("-fx-font-weight: bold; -fx-font-size: 2em;");
             gp.add(la, j, k++, 2, 1);
         } else {
@@ -156,7 +160,7 @@ class MetadataOverview extends StackPane {
         }
 
         // Show author information.
-        Collection<? extends Responsibility> contacts = this.METADATA.getContacts();
+        Collection<? extends Responsibility> contacts = this.metadata.getContacts();
         if (!contacts.isEmpty()) {
             Responsibility contact = contacts.iterator().next();
             Collection<? extends Party> parties = contact.getParties();
@@ -165,6 +169,7 @@ class MetadataOverview extends StackPane {
                 if (party.getName() != null) {
                     Label partyType = new Label("Party");
                     Label partyValue = new Label(party.getName().toString());
+                    partyValue.setWrapText(true);
                     if (party instanceof DefaultOrganisation) {
                         partyType.setText("Organisation");
                     } else if (party instanceof DefaultIndividual) {
@@ -182,9 +187,8 @@ class MetadataOverview extends StackPane {
 
         comboBox.setOnAction(e -> {
             gpi.getChildren().clear();
-            Identification id = m.get(comboBox.getValue().toString());
-
-            if (comboBox.getValue().toString().equals("No data to show")) {
+            Identification id = m.get(comboBox.getValue());
+            if (comboBox.getValue().equals("No data to show")) {
                 return;
             }
 
@@ -193,7 +197,8 @@ class MetadataOverview extends StackPane {
             if (ab != null) {
                 InternationalString abs = (InternationalString) ab;
                 Label crd = new Label("Abstract");
-                Label crdValue = new Label(abs.toString(LOCALE));
+                Label crdValue = new Label(abs.toString(locale));
+                crdValue.setWrapText(true);
                 gpi.add(crd, 0, 1);
                 gpi.add(crdValue, 1, 1);
             } else {
@@ -202,6 +207,7 @@ class MetadataOverview extends StackPane {
                     InternationalString credit = credits.iterator().next();
                     Label crd = new Label("Credit");
                     Label crdValue = new Label(credit.toString());
+                    crdValue.setWrapText(true);
                     gpi.add(crd, 0, 1);
                     gpi.add(crdValue, 1, 1);
                 }
@@ -212,19 +218,21 @@ class MetadataOverview extends StackPane {
                 TopicCategory tc = tcs.iterator().next();
                 Label topicC = new Label("Topic Category");
                 Label topicValue = new Label(tc.toString());
+                topicValue.setWrapText(true);
                 gpi.add(topicC, 0, 2);
                 gpi.add(topicValue, 1, 2);
             }
 
             if (!id.getCitation().getDates().isEmpty()) {
                 CitationDate dateAndType = id.getCitation().getDates().iterator().next();
-                DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.MEDIUM,
LOCALE);
+                DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.MEDIUM,
locale);
                 String dateStr = dateFormat.format(dateAndType.getDate());
                 String s = dateAndType.getDateType().toString();
                 s = s.replace("DateType[", "");
                 s = s.replace("]", "");
                 Label dt = new Label("Date type: " + s.toLowerCase());
                 Label dtValue = new Label(dateStr);
+                dtValue.setWrapText(true);
                 gpi.add(dt, 0, 3);
                 gpi.add(dtValue, 1, 3);
             }
@@ -232,11 +240,13 @@ class MetadataOverview extends StackPane {
             if (id instanceof DataIdentification) {
                 Label topicC = new Label("Object type");
                 Label topicValue = new Label("Data");
+                topicValue.setWrapText(true);
                 gpi.add(topicC, 0, 4);
                 gpi.add(topicValue, 1, 4);
             } else {
                 Label topicC = new Label("Object type");
                 Label topicValue = new Label("Service");
+                topicValue.setWrapText(true);
                 gpi.add(topicC, 0, 4);
                 gpi.add(topicValue, 1, 4);
             }
@@ -246,10 +256,11 @@ class MetadataOverview extends StackPane {
             String typeList = "Spatial representation type: ";
             while (its.hasNext()) {
                 SpatialRepresentationType spatialRepresentationType = its.next();
-                typeList += spatialRepresentationType.toString().toLowerCase(LOCALE).replace("spatialrepresentationtype[",
"").replace(']', '\0') + ", ";
+                typeList += spatialRepresentationType.toString().toLowerCase(locale).replace("spatialrepresentationtype[",
"").replace(']', '\0') + ", ";
             }
             if (!typeList.equals("Spatial representation type: ")) {
                 Label list = new Label(typeList.substring(0, typeList.length() - 2));
+                list.setWrapText(true);
                 gpi.add(list, 0, 5, 2, 1);
             }
 
@@ -262,6 +273,7 @@ class MetadataOverview extends StackPane {
                     GeographicExtent ge = it.next();
                     Label geoEx = new Label("Zone");
                     Label geoExValue = new Label(ge.toString());
+                    geoExValue.setWrapText(true);
                     if (ge instanceof GeographicBoundingBox) {
                         geoEx.setText("");
                         GeographicBoundingBox gbd = (GeographicBoundingBox) ge;
@@ -281,10 +293,9 @@ class MetadataOverview extends StackPane {
                     }
                 }
             }
-
         });
 
-        Event.fireEvent(comboBox, new Event(ACTION));
+        Event.fireEvent(comboBox, new ActionEvent());
         gp.add(gpi, j, k++, 2, 1);
 
         int ind = 0;
@@ -295,25 +306,18 @@ class MetadataOverview extends StackPane {
                 n.setStyle("-fx-padding: 0 0 10 0; -fx-font-weight: bold; -fx-font-size:
2em;");
             }
         }
-
-        for (Node n : gpi.getChildren()) {
-            n.setStyle("-fx-padding: 0 0 10 0;");
-        }
+        gpi.getChildren().forEach(n -> n.setStyle("-fx-padding: 0 0 10 0;"));
 
         return gp;
     }
 
     private Canvas createMap(double north, double east, double south, double west) {
         Canvas can = new Canvas();
-        final File file = new File("/home/admin/Documents/WorldMap360*180.png");
-        Image image;
-        String localUrl;
-        try {
-            localUrl = file.toURI().toURL().toString();
-            image = new Image(localUrl);
-        } catch (MalformedURLException ex) {
-            Logger.getLogger(MetadataOverview.class.getName()).log(Level.SEVERE, null, ex);
-            return null;
+        Image image = null;
+        try (InputStream in = MetadataOverview.class.getResourceAsStream("WorldMap360x180.png"))
{
+            image = new Image(in);
+        } catch (IOException e) {
+            // TODO
         }
         if (image.errorProperty().getValue()) {
             return null;
@@ -354,21 +358,19 @@ class MetadataOverview extends StackPane {
         gp.setVgap(10.00);
         int j = 0, k = 1;
 
-        Collection<? extends ReferenceSystem> referenceSystemInfos = METADATA.getReferenceSystemInfo();
+        Collection<? extends ReferenceSystem> referenceSystemInfos = metadata.getReferenceSystemInfo();
         if (!referenceSystemInfos.isEmpty()) {
             ReferenceSystem referenceSystemInfo = referenceSystemInfos.iterator().next();
             Label rsiValue = new Label("Reference system infos: " + referenceSystemInfo.getName().toString());
+            rsiValue.setWrapText(true);
             gp.add(rsiValue, j, k++);
         }
 
-        Collection<? extends SpatialRepresentation> sris = this.METADATA.getSpatialRepresentationInfo();
+        Collection<? extends SpatialRepresentation> sris = this.metadata.getSpatialRepresentationInfo();
         if (sris.isEmpty()) {
-            Label noData = new Label("No data found.");
-            noData.setStyle("-fx-text-fill: red;");
-            gp.add(noData, ++j, k++, 2, 1);
             return gp;
         }
-        NumberFormat numberFormat = getIntegerInstance(LOCALE);
+        NumberFormat numberFormat = NumberFormat.getIntegerInstance(locale);
         for (SpatialRepresentation sri : sris) {
             String currentValue = "• ";
             if (sri instanceof DefaultGridSpatialRepresentation) {
@@ -377,14 +379,15 @@ class MetadataOverview extends StackPane {
                 Iterator<? extends Dimension> it = sr.getAxisDimensionProperties().iterator();
                 while (it.hasNext()) {
                     Dimension dim = it.next();
-                    currentValue += numberFormat.format(dim.getDimensionSize()) + " " + getCodeTitle(dim.getDimensionName())
+ " * ";
+                    currentValue += numberFormat.format(dim.getDimensionSize()) + " " + Types.getCodeTitle(dim.getDimensionName())
+ " * ";
                 }
                 currentValue = currentValue.substring(0, currentValue.length() - 3);
                 Label spRep = new Label(currentValue);
                 gp.add(spRep, j, k++, 2, 1);
                 if (sr.getCellGeometry() != null) {
                     Label cellGeo = new Label("Cell geometry:");
-                    Label cellGeoValue = new Label(getCodeTitle(sr.getCellGeometry()).toString());
+                    Label cellGeoValue = new Label(Types.getCodeTitle(sr.getCellGeometry()).toString());
+                    cellGeoValue.setWrapText(true);
                     gp.add(cellGeo, j, k);
                     gp.add(cellGeoValue, ++j, k++);
                     j = 0;
@@ -394,9 +397,9 @@ class MetadataOverview extends StackPane {
         return gp;
     }
 
-    private ComboBox createComboBox(HashMap<String, Identification> m) {
-        ComboBox cb = new ComboBox();
-        Collection<? extends Identification> ids = this.METADATA.getIdentificationInfo();
+    private ComboBox<String> createComboBox(final Map<String, Identification>
m) {
+        ComboBox<String> cb = new ComboBox<>();
+        Collection<? extends Identification> ids = this.metadata.getIdentificationInfo();
         ObservableList<String> options = FXCollections.observableArrayList();
         int i = 1;
         if (ids.size() > 1) {
@@ -424,9 +427,4 @@ class MetadataOverview extends StackPane {
         }
         return cb;
     }
-
-    public final String getFromFile() {
-        return FROMFILE;
-    }
-
 }
diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/ResourceView.java
b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/ResourceView.java
index 5a9af51..d2fd25c 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/ResourceView.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/ResourceView.java
@@ -21,13 +21,16 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import javafx.collections.ListChangeListener;
 import javafx.collections.ObservableList;
+import javafx.concurrent.Task;
 import javafx.event.Event;
 import javafx.scene.Node;
 import javafx.scene.control.Alert;
 import javafx.scene.control.ContextMenu;
 import javafx.scene.control.Label;
 import javafx.scene.control.MenuItem;
+import javafx.scene.control.ProgressIndicator;
 import javafx.scene.control.TreeItem;
 import javafx.scene.control.TreeView;
 import javafx.scene.input.DataFormat;
@@ -38,12 +41,14 @@ import javafx.scene.input.TransferMode;
 import javafx.scene.control.SplitPane;
 import javafx.scene.layout.VBox;
 import javafx.scene.paint.Color;
+import org.apache.sis.gui.dataset.FeatureTable;
 import org.apache.sis.internal.storage.folder.FolderStoreProvider;
 import org.apache.sis.metadata.iso.DefaultMetadata;
 import org.apache.sis.storage.Aggregate;
 import org.apache.sis.storage.DataStore;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.DataStores;
+import org.apache.sis.storage.FeatureSet;
 import org.apache.sis.storage.Resource;
 import org.apache.sis.storage.StorageConnector;
 
@@ -51,16 +56,27 @@ import org.apache.sis.storage.StorageConnector;
 /**
  * Show resources available in data files.
  *
- * @author Smaniotto Enzo
+ * @author  Smaniotto Enzo
+ * @version 1.0
+ * @since   1.0
+ * @module
  */
 public class ResourceView {
 
     private final TreeItem<Label> root = new TreeItem<>(new Label("Files"));
+
+    // Those variables are used to temporary fix a bug while the FeatureTable is open (the
root item erase his childrens so their disappear of the TreeView). this will have to be corrected
later.
+    private final ObservableList<TreeItem<Label>> temporarySauv;
+
+    private List<TreeItem<Label>> temp = new ArrayList<>();
+
     public final SplitPane pane = new SplitPane();
+
+    //This map link the respective Tree Items to their own Label in order to keep the informations
of the document's name and of it location (stocked in the Label) to the item in the TreeView.
Usefull to know which element is selected.
     private final Map<Label, TreeItem<?>> labelToItem = new HashMap<>();
 
-    // TODO: What is that?
-    private final List<String> LABINTRV = new ArrayList<>();
+    // This List contain all the elements present in the TreeView, referenced by their id
(set to the specific location of each file). Used to know if a file is already open.
+    private final List<String> labToTrv = new ArrayList<>();
 
     private Label sauvLabel, parent;
 
@@ -91,7 +107,7 @@ public class ResourceView {
                 if (db.hasFiles()) {
                     success = true;
                 }
-                List<?> fileList = (List<?>) db.getContent(DataFormat.FILES);
+                List<?> fileList = (List<?>) db.getContent(DataFormat.FILES);
// To open multiple files in one drop.
                 for (Object item : fileList) {
                     File f = (File) item;
                     openFile(f);
@@ -100,19 +116,31 @@ public class ResourceView {
             event.setDropCompleted(success);
             event.consume();
         });
+
+        // Link to the temporary varaible see above. This is a temporary part.
+        temporarySauv = root.getChildren();
+        temporarySauv.addListener((ListChangeListener.Change<? extends TreeItem<Label>>
c) -> {
+            c.next();
+            if (c.wasRemoved()) {
+                temp.addAll(c.getRemoved());
+            }
+        });
+
         pane.getItems().add(resources);
     }
 
-    private MetadataOverview getContent() {
+    // Get the view of the opened element, return null otherwise.
+    private Object getContent() {
         final ObservableList<Node> items = pane.getItems();
         if (items.size() >= 2) {
-            return (MetadataOverview) items.get(1);
+            return items.get(1);
         } else {
             return null;
         }
     }
 
-    private void setContent(final MetadataOverview content) {
+    // Set the view of the opened element.
+    private void setContent(final Node content) {
         final ObservableList<Node> items = pane.getItems();
         if (items.size() >= 2) {
             items.set(1, content);
@@ -126,18 +154,41 @@ public class ResourceView {
         close.setOnAction(ac -> {
             root.getChildren().remove(labelToItem.get(lab));
             labelToItem.remove(lab);
-            LABINTRV.remove(lab.getId());
-            final MetadataOverview content = getContent();
-            if (content != null) {
-                if (lab.getId().equals(content.getFromFile())) {
-                    setContent(null);
+            labToTrv.remove(lab.getId());
+            final Object content = getContent();
+            if (content != null && content instanceof FeatureTable) {
+                pane.getItems().remove(1);
+            }
+            if (content != null && content instanceof MetadataOverview) {
+                if (lab.getId().equals(((MetadataOverview) content).fromFile)) {
+                    setContent(new Label("   Please choose a file to open   "));
+               }
+            }
+        });
+        MenuItem feature = new MenuItem("Open Feature");
+        feature.setOnAction(ac -> {
+            try {
+                DataStore ds = DataStores.open(lab.getId());
+                if (ds instanceof FeatureSet) {
+                    root.getChildren().remove(labelToItem.get(lab));
+                    addFeaturePanel(lab.getId());
                 }
+            } catch (DataStoreException ex) {
+                final Alert alert = new Alert(Alert.AlertType.ERROR);
+                alert.setTitle("An error has occurred");
+                lab.setWrapText(true);
+                lab.setMaxWidth(650);
+                VBox vb = new VBox();
+                vb.getChildren().add(lab);
+                alert.getDialogPane().setContent(vb);
+                alert.show();
             }
         });
-        ContextMenu cm = new ContextMenu(close);
+        ContextMenu cm = new ContextMenu(feature, close);
         lab.setContextMenu(cm);
     }
 
+    // Define what happens when an element of the TreeView is clicked.
     private void setOnClick(Label lab) {
         addContextMenu(lab);
         lab.setOnMouseClicked(click -> {
@@ -145,42 +196,22 @@ public class ResourceView {
                 if (sauvLabel != null) {
                     sauvLabel.setTextFill(Color.BLACK);
                 }
-                addMetadatPanel(lab.getId());
+                addMetadatPanel(null, lab.getId());
                 sauvLabel = lab;
                 lab.setTextFill(Color.RED);
             }
         });
     }
 
-    private boolean checkMetaPanel(String filePath) {
-        MetadataOverview meta;
-        try {
-            DataStore ds = DataStores.open(filePath);
-            meta = new MetadataOverview(new DefaultMetadata(ds.getMetadata()), filePath);
-            return true;
-        } catch (DataStoreException e) {
-            final Alert alert = new Alert(Alert.AlertType.ERROR);
-            alert.setTitle("An error was occur");
-            Label lab = new Label(e.getMessage());
-            lab.setWrapText(true);
-            lab.setMaxWidth(650);
-            VBox vb = new VBox();
-            vb.getChildren().add(lab);
-            alert.getDialogPane().setContent(vb);
-            alert.show();
-            return false;
-        }
-    }
-
-    private void addMetadatPanel(String filePath) {
-        MetadataOverview meta;
+    private void addFeaturePanel(String filePath) {
         try {
             DataStore ds = DataStores.open(filePath);
-            meta = new MetadataOverview(new DefaultMetadata(ds.getMetadata()), filePath);
-            setContent(meta);
+            setContent(new FeatureTable(ds, 18));
+            root.getChildren().addAll(temp);
+            temp.clear();
         } catch (DataStoreException e) {
             final Alert alert = new Alert(Alert.AlertType.ERROR);
-            alert.setTitle("An error was occur");
+            alert.setTitle("An error has occurred");
             Label lab = new Label(e.getMessage());
             lab.setWrapText(true);
             lab.setMaxWidth(650);
@@ -192,21 +223,42 @@ public class ResourceView {
     }
 
     private void addMetadatPanel(Resource res, String filePath) {
-        MetadataOverview meta;
-        try {
-            meta = new MetadataOverview(((DefaultMetadata) res.getMetadata()), filePath);
+        Task<MetadataOverview> task = new Task<MetadataOverview>() {
+            @Override
+            protected MetadataOverview call() throws DataStoreException {
+                MetadataOverview meta;
+                if (res != null) {
+                    meta = new MetadataOverview(((DefaultMetadata) res.getMetadata()), filePath);
+                } else {
+                    DataStore ds = DataStores.open(filePath);
+                    meta = new MetadataOverview(new DefaultMetadata(ds.getMetadata()), filePath);
+                }
+                return meta;
+            }
+        };
+        task.setOnSucceeded(wse -> {
+            final MetadataOverview meta = task.getValue();
             setContent(meta);
-        } catch (DataStoreException e) {
+        });
+        task.setOnRunning(wse -> {
+            ProgressIndicator p = new ProgressIndicator(-1);
+            p.setPrefSize(17, 18);
+            setContent(p);
+        });
+        task.setOnFailed(wse -> {
             final Alert alert = new Alert(Alert.AlertType.ERROR);
             alert.setTitle("An error was occur");
-            Label lab = new Label(e.getMessage());
+            Label lab = new Label(task.getException().getMessage());
             lab.setWrapText(true);
             lab.setMaxWidth(650);
             VBox vb = new VBox();
             vb.getChildren().add(lab);
             alert.getDialogPane().setContent(vb);
             alert.show();
-        }
+        });
+        final Thread thread = new Thread(task);
+        thread.setDaemon(true);
+        thread.start();
     }
 
     public void open(final List<File> files) {
@@ -220,10 +272,19 @@ public class ResourceView {
     }
 
     private void openFile(File f) {
-        if (checkMetaPanel(f.getAbsolutePath())) {
+        Task<Void> t = new Task<Void>() {
+            @Override
+            protected Void call() throws DataStoreException {
+                MetadataOverview meta;
+                DataStore ds = DataStores.open(f.getAbsolutePath());
+                meta = new MetadataOverview(new DefaultMetadata(ds.getMetadata()), f.getAbsolutePath());
+                return null;
+            }
+        };
+        t.setOnSucceeded(ac -> {
             Label label = new Label(f.getName());
             label.setId(f.getAbsolutePath());
-            if (LABINTRV.contains(f.getAbsolutePath())) {
+            if (labToTrv.contains(f.getAbsolutePath())) {
                 for (Label elem : labelToItem.keySet()) {
                     if (elem.getId().equals(f.getAbsolutePath())) {
                         Event.fireEvent(elem, new MouseEvent(MouseEvent.MOUSE_CLICKED, 0,
0, 0, 0, MouseButton.PRIMARY, 1, true, true, true, true, true, true, true, true, true, true,
null));
@@ -233,19 +294,34 @@ public class ResourceView {
                 setOnClick(label);
                 TreeItem<Label> tItem = new TreeItem<>(label);
                 labelToItem.put(label, tItem);
-                LABINTRV.add(f.getAbsolutePath());
+                labToTrv.add(f.getAbsolutePath());
                 root.getChildren().add(tItem);
             }
-        }
+        });
+        t.setOnFailed(ac -> {
+            final Alert alert = new Alert(Alert.AlertType.ERROR);
+            alert.setTitle("An error was occur");
+            Label lab = new Label(t.getException().getMessage());
+            lab.setWrapText(true);
+            lab.setMaxWidth(650);
+            VBox vb = new VBox();
+            vb.getChildren().add(lab);
+            alert.getDialogPane().setContent(vb);
+            alert.show();
+        });
+        final Thread thread = new Thread(t);
+        thread.setDaemon(true);
+        thread.start();
     }
 
+    // For the directory, the methods "setOnClick" and "addContextMenu" are redefine inside.
     private void openDirectory(File firstFile) {
-        if (!LABINTRV.contains("[Aggregate] " + firstFile.getName())) {
+        if (!labToTrv.contains("[Aggregate] " + firstFile.getName())) {
             DataStore resource = null;
             try {
                 resource = FolderStoreProvider.INSTANCE.open(new StorageConnector(firstFile));
             } catch (DataStoreException ex) {
-                ex.getMessage();
+                ex.getMessage();                    // TODO: needs better handling.
             }
             if (resource instanceof Aggregate) {
                 parent = new Label("[Aggregate] " + firstFile.getName());
@@ -262,11 +338,14 @@ public class ResourceView {
                 close.setOnAction(ac -> {
                     root.getChildren().remove(labelToItem.get(cl));
                     labelToItem.remove(cl);
-                    LABINTRV.remove(parent.getText());
-                    final MetadataOverview content = getContent();
-                    if (content != null) {
-                        if (parent.getId().equals(content.getFromFile())) {
-                            setContent(null);
+                    labToTrv.remove(parent.getText());
+                    final Object content = getContent();
+                    if (content != null && content instanceof FeatureTable) {
+                        pane.getItems().remove(1);
+                    }
+                    if (content != null && content instanceof MetadataOverview) {
+                        if (parent.getId().equals(((MetadataOverview) content).fromFile))
{
+                            setContent(new Label("   Please choose a file to open   "));
                         }
                     }
                 });
@@ -290,13 +369,21 @@ public class ResourceView {
                         ti.getChildren().add(tiChild);
                     }
                 } catch (DataStoreException ex) {
-                    System.out.println(ex.getMessage());        // TODO: NO!!!!!
+                    final Alert alert = new Alert(Alert.AlertType.ERROR);
+                    alert.setTitle("An error was occur");
+                    Label lab = new Label(ex.getMessage());
+                    lab.setWrapText(true);
+                    lab.setMaxWidth(650);
+                    VBox vb = new VBox();
+                    vb.getChildren().add(lab);
+                    alert.getDialogPane().setContent(vb);
+                    alert.show();
                 }
                 root.getChildren().add(ti);
-                LABINTRV.add(parent.getText());
+                labToTrv.add(parent.getText());
                 labelToItem.put(parent, ti);
             }
-        } else { // If the file is already open.
+        } else {                                                // If the file is already
open.
             if (sauvLabel != null) {
                 sauvLabel.setTextFill(Color.BLACK);
             }
@@ -306,7 +393,7 @@ public class ResourceView {
                     elem.getValue().setTextFill(Color.RED);
                 }
             });
-            setContent(null);
+            setContent(new Label("   Please choose a file to open   "));
         }
     }
 }
diff --git a/application/sis-javafx/src/main/resources/org/apache/sis/gui/metadata/WorldMap360x180.png
b/application/sis-javafx/src/main/resources/org/apache/sis/gui/metadata/WorldMap360x180.png
new file mode 100644
index 0000000..dd5cf6b
Binary files /dev/null and b/application/sis-javafx/src/main/resources/org/apache/sis/gui/metadata/WorldMap360x180.png
differ


Mime
View raw message