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 1051b8d7dc23c70ad968523c14ccf93bc9822618
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Wed Dec 29 02:21:10 2021 +0100

    Add a menu item for showing a metadata value in a dialog window.
---
 .../org/apache/sis/gui/metadata/MetadataTree.java  | 75 +++++++++++++++++++---
 .../sis/gui/metadata/StandardMetadataTree.java     |  2 +-
 .../org/apache/sis/internal/gui/PropertyView.java  | 38 ++++++++---
 .../org/apache/sis/internal/gui/Resources.java     | 10 +++
 .../apache/sis/internal/gui/Resources.properties   |  2 +
 .../sis/internal/gui/Resources_fr.properties       |  2 +
 6 files changed, 110 insertions(+), 19 deletions(-)

diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataTree.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataTree.java
index 4c2f9cb..1b11850 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataTree.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/MetadataTree.java
@@ -29,6 +29,9 @@ import javafx.beans.property.ReadOnlyStringWrapper;
 import javafx.beans.property.SimpleObjectProperty;
 import javafx.beans.value.ObservableValue;
 import javafx.collections.ObservableList;
+import javafx.scene.control.Dialog;
+import javafx.scene.control.DialogPane;
+import javafx.scene.control.ButtonType;
 import javafx.scene.control.ContextMenu;
 import javafx.scene.control.MenuItem;
 import javafx.scene.control.TreeItem;
@@ -46,6 +49,8 @@ import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.internal.util.PropertyFormat;
 import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.gui.Resources;
+import org.apache.sis.internal.gui.PropertyView;
+import org.apache.sis.internal.gui.ExceptionReporter;
 import org.apache.sis.util.collection.TreeTable;
 import org.apache.sis.util.collection.TableColumn;
 import org.apache.sis.util.resources.Vocabulary;
@@ -109,6 +114,19 @@ public class MetadataTree extends 
TreeTableView<TreeTable.Node> {
     public final ObjectProperty<TreeTable> contentProperty;
 
     /**
+     * Content of a dialog showing the value of selected row.
+     *
+     * @see #showPropertyValue(Object)
+     */
+    private PropertyView propertyViewer;
+
+    /**
+     * The dialog showing the property value. We keep the instance for 
preserving
+     * its size and position if the user modifies them.
+     */
+    private Dialog<Void> propertyDialog;
+
+    /**
      * Implementation of {@link MetadataTree#contentProperty} as a named class 
for more readable stack trace.
      * This class verifies the constraints documented in {@link 
MetadataTree#setContent(TreeTable)}.
      */
@@ -246,6 +264,9 @@ check:      if (data != null) {
                                     final TreeTable oldValue, final TreeTable  
newValue)
     {
         final MetadataTree s = (MetadataTree) ((ContentProperty) 
property).getBean();
+        if (s.propertyViewer != null) {
+            s.propertyViewer.clear();
+        }
         TreeItem<TreeTable.Node> root = null;
         if (newValue != null) {
             root = new Item(newValue.getRoot());
@@ -393,30 +414,35 @@ check:      if (data != null) {
         protected final ContextMenu menu;
 
         /**
-         * The menu item for copying current row.
+         * The menu item for copying current row or viewing in a dialog box.
          */
-        protected final MenuItem copy;
+        private final MenuItem view, copy;
 
         /**
          * Creates a new row for the given tree table.
          */
         @SuppressWarnings("ThisEscapedInObjectConstruction")
-        Row(final TreeTableView<TreeTable.Node> view) {
-            final MetadataTree md = (MetadataTree) view;
+        Row(final TreeTableView<TreeTable.Node> owner) {
+            final MetadataTree md = (MetadataTree) owner;
             final Resources localized = Resources.forLocale(md.getLocale());
+            view = new MenuItem(localized.getString(Resources.Keys.View));
             copy = new MenuItem(localized.getString(Resources.Keys.Copy));
-            menu = new ContextMenu(copy);
+            menu = new ContextMenu(view, copy);
             copy.setOnAction(this);
+            view.setOnAction((h) -> ((MetadataTree) 
getTreeTableView()).showPropertyValue(getValue()));
         }
 
         /**
-         * Invoked when a new row is selected. This method sets the contextual 
menu on the row.
+         * Invoked when a new row is selected.
+         * This method sets the contextual menu on the row and updates the 
disabled state.
          */
         @Override
         protected void updateItem​(final TreeTable.Node item, final boolean 
empty) {
             super.updateItem(item, empty);
             setContextMenu(empty ? null : menu);
-            copy.setDisable(empty || getValue() == null);
+            final boolean disabled = empty || getValue() == null;
+            view.setDisable(disabled);
+            copy.setDisable(disabled);
         }
 
         /**
@@ -432,16 +458,47 @@ check:      if (data != null) {
         }
 
         /**
-         * Invoked when user selected a menu item.
+         * Invoked when user selected a "Copy" or "Copy as" menu item.
+         * The default implementation handles the "Copy" action,
+         * but subclasses can override for handling other copy variants.
          */
         @Override
         public void handle(final ActionEvent event) {
             final Object value = getValue();
             if (value != null) {
                 final ClipboardContent content = new ClipboardContent();
-                content.putString(value.toString());
+                content.putString(toString(value));
                 Clipboard.getSystemClipboard().setContent(content);
             }
         }
+
+        /**
+         * Returns a string representation of the given object
+         * for the purpose of a "copy to clipboard" operation.
+         */
+        static String toString(final Object obj) {
+            if (obj instanceof Throwable) {
+                return ExceptionReporter.getStackTrace((Throwable) obj);
+            }
+            return obj.toString();
+        }
+    }
+
+    /**
+     * Shows the given value in a dialog box.
+     */
+    private void showPropertyValue(final Object value) {
+        if (propertyViewer == null) {
+            propertyViewer = new PropertyView(getLocale(), null, null);
+            propertyDialog = new Dialog<>();
+            propertyDialog.setResizable(true);
+            
propertyDialog.setTitle(Resources.forLocale(getLocale()).getString(Resources.Keys.PropertyValue));
+            propertyDialog.initOwner(getScene().getWindow());
+            final DialogPane pane = propertyDialog.getDialogPane();
+            pane.contentProperty().bind(propertyViewer.view);
+            pane.getButtonTypes().add(ButtonType.CLOSE);
+        }
+        propertyViewer.set(value, null);
+        propertyDialog.show();
     }
 }
diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/StandardMetadataTree.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/StandardMetadataTree.java
index afe4730..f81fda6 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/StandardMetadataTree.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/metadata/StandardMetadataTree.java
@@ -203,7 +203,7 @@ public class StandardMetadataTree extends MetadataTree {
                             text = output.toString();
                             content.put(DataFormats.ISO_19139, text);
                         } else {
-                            text = obj.toString();
+                            text = toString(obj);
                         }
                         content.putString(text);
                         Clipboard.getSystemClipboard().setContent(content);
diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/PropertyView.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/PropertyView.java
index 3b10cb2..c4df1ee 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/PropertyView.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/internal/gui/PropertyView.java
@@ -32,6 +32,7 @@ import java.awt.image.RenderedImage;
 import javafx.beans.value.ChangeListener;
 import javafx.beans.value.ObservableValue;
 import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleObjectProperty;
 import javafx.geometry.Insets;
 import javafx.scene.Node;
 import javafx.scene.text.Font;
@@ -70,8 +71,9 @@ public final class PropertyView extends 
CompoundFormat<Object> implements Change
 
     /**
      * The node used for showing {@link #value}.
+     * The node is created by {@link #set(Object, Rectangle)}.
      */
-    private final ObjectProperty<Node> view;
+    public final ObjectProperty<Node> view;
 
     /**
      * Shows the {@linkplain #value} as plain text.
@@ -94,8 +96,10 @@ public final class PropertyView extends 
CompoundFormat<Object> implements Change
     /**
      * The pane containing {@link #imageView}. We use that pane for allowing a 
background color to be specified.
      * A future version may also use that pane for putting more visual 
components on top or below the image.
+     *
+     * @see #getImageCanvas()
      */
-    private final Pane imageCanvas;
+    private Pane imageCanvas;
 
     /**
      * The group of all components related to image, created when first needed.
@@ -131,19 +135,19 @@ public final class PropertyView extends 
CompoundFormat<Object> implements Change
      * Creates a new property view.
      *
      * @param  locale      the locale for numbers formatting.
-     * @param  view        the property where to set the node showing the 
value.
+     * @param  view        the property where to set the node showing the 
value, or {@code null} for a default one.
      * @param  background  the image background color, or {@code null} if none.
      */
     @SuppressWarnings("ThisEscapedInObjectConstruction")
-    public PropertyView(final Locale locale, final ObjectProperty<Node> view, 
final ObjectProperty<Background> background) {
+    public PropertyView(final Locale locale, ObjectProperty<Node> view, final 
ObjectProperty<Background> background) {
         super(locale, null);
+        if (view == null) {
+            view = new SimpleObjectProperty<>(this, "view");
+        }
         this.view = view;
-        imageCanvas = new Pane();
         if (background != null) {
-            imageCanvas.backgroundProperty().bind(background);
+            getImageCanvas().backgroundProperty().bind(background);
         }
-        imageCanvas.widthProperty() .addListener(this);
-        imageCanvas.heightProperty().addListener(this);
     }
 
     /**
@@ -292,12 +296,25 @@ public final class PropertyView extends 
CompoundFormat<Object> implements Change
     }
 
     /**
+     * Returns the pane containing {@link #imageView}.
+     */
+    private Pane getImageCanvas() {
+        if (imageCanvas == null) {
+            imageCanvas = new Pane();
+            imageCanvas.widthProperty() .addListener(this);
+            imageCanvas.heightProperty().addListener(this);
+        }
+        return imageCanvas;
+    }
+
+    /**
      * Sets the property value to the given image.
      *
      * @param  image          the property value to set, or {@code null}.
      * @param  boundsChanged  whether {@link #visibleImageBounds} changed 
since last call.
      */
     private Node setImage(final RenderedImage image, final boolean 
boundsChanged) {
+        final Pane imageCanvas = getImageCanvas();
         ImageView node = imageView;
         if (node == null) {
             node = new ImageView();
@@ -413,7 +430,10 @@ public final class PropertyView extends 
CompoundFormat<Object> implements Change
         value = null;
         view.set(null);
         if (textView != null) {
-            textView .setText (null);
+            textView.setText(null);
+        }
+        if (listView != null) {
+            listView.getItems().clear();
         }
         if (imageView != null) {
             ImageConverter.clear(imageView);
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 b693899..518467f 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
@@ -318,6 +318,11 @@ public final class Resources extends IndexedResourceBundle 
{
         public static final short Orthographic = 52;
 
         /**
+         * Property value
+         */
+        public static final short PropertyValue = 68;
+
+        /**
          * Range of values…
          */
         public static final short RangeOfValues = 56;
@@ -368,6 +373,11 @@ public final class Resources extends IndexedResourceBundle 
{
         public static final short UTM = 45;
 
         /**
+         * View
+         */
+        public static final short View = 67;
+
+        /**
          * Visualize
          */
         public static final short Visualize = 34;
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 cbaefa2..70125be 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
@@ -72,6 +72,7 @@ Open                   = Open\u2026
 OpenDataFile           = Open data file
 OpenRecentFile         = Open recent file
 Orthographic           = Orthographic
+PropertyValue          = Property value
 RangeOfValues          = Range of values\u2026
 SelectCRS              = Select a coordinate reference system
 SelectCrsByContextMenu = For changing the projection, use contextual menu on 
the map.
@@ -82,6 +83,7 @@ SystemMonitor          = System monitor
 TabularData            = Tabular data
 TileIndexStart         = Tile index start
 UTM                    = Universal Transverse Mercator
+View                   = View
 Visualize              = Visualize
 WebSite                = Web site
 Windows                = Windows
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 06e8ac6..d580bee 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
@@ -77,6 +77,7 @@ Open                   = Ouvrir\u2026
 OpenDataFile           = Ouvrir un fichier de donn\u00e9es
 OpenRecentFile         = Ouvrir un fichier r\u00e9cent
 Orthographic           = Orthographique
+PropertyValue          = Valeur de la propri\u00e9t\u00e9
 RangeOfValues          = Plage de valeurs\u2026
 SelectCRS              = Choisir un syst\u00e8me de r\u00e9f\u00e9rence des 
coordonn\u00e9es
 SelectCrsByContextMenu = Pour changer la projection, utilisez le menu 
contextuel sur la carte.
@@ -87,6 +88,7 @@ SystemMonitor          = Moniteur syst\u00e8me
 TabularData            = Tableau de valeurs
 TileIndexStart         = D\u00e9but des indices de tuiles
 UTM                    = Transverse universelle de Mercator
+View                   = Afficher
 Visualize              = Visualiser
 WebSite                = Site web
 Windows                = Fen\u00eatres

Reply via email to