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