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


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new fd6ef02230 Handle the status bar layout outside `GridView`. Handle 
more common properties in the `ViewAndControls` parent class.
fd6ef02230 is described below

commit fd6ef0223071cb8b35048333e92bd4121206c28e
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Sat May 21 16:03:48 2022 +0200

    Handle the status bar layout outside `GridView`.
    Handle more common properties in the `ViewAndControls` parent class.
---
 .../apache/sis/gui/coverage/CoverageControls.java  |  44 ++-------
 .../apache/sis/gui/coverage/CoverageExplorer.java  |  16 +--
 .../org/apache/sis/gui/coverage/GridControls.java  |  39 ++------
 .../org/apache/sis/gui/coverage/GridViewSkin.java  |  15 +--
 .../apache/sis/gui/coverage/ViewAndControls.java   | 107 ++++++++++++---------
 .../apache/sis/gui/dataset/ResourceExplorer.java   |   3 +-
 6 files changed, 91 insertions(+), 133 deletions(-)

diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageControls.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageControls.java
index 32127410b5..d8f24b426e 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageControls.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageControls.java
@@ -18,7 +18,6 @@ package org.apache.sis.gui.coverage;
 
 import java.util.Locale;
 import javafx.scene.control.TitledPane;
-import javafx.scene.layout.BorderPane;
 import javafx.scene.layout.GridPane;
 import javafx.scene.layout.Region;
 import javafx.scene.layout.VBox;
@@ -45,7 +44,7 @@ import org.apache.sis.util.resources.Vocabulary;
  * The controls are updated when the coverage shown in {@link CoverageCanvas} 
is changed.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.3
  * @since   1.1
  * @module
  */
@@ -67,20 +66,10 @@ final class CoverageControls extends ViewAndControls {
      */
     private final IsolineRenderer isolines;
 
-    /**
-     * The controls for changing {@link #view}.
-     */
-    private final TitledPane[] controls;
-
-    /**
-     * The image together with the status bar.
-     */
-    private final BorderPane imageAndStatus;
-
     /**
      * Creates a new set of coverage controls.
      *
-     * @param  owner  the widget which create this view. Can not be null.
+     * @param  owner  the widget which creates this view. Can not be null.
      */
     CoverageControls(final CoverageExplorer owner) {
         super(owner);
@@ -91,8 +80,6 @@ final class CoverageControls extends ViewAndControls {
         view = new CoverageCanvas(locale);
         view.setBackground(Color.BLACK);
         view.statusBar = new StatusBar(owner.referenceSystems, view);
-        imageAndStatus = new BorderPane(view.getView());
-        imageAndStatus.setBottom(view.statusBar.getView());
         final MapMenu menu = new MapMenu(view);
         menu.addReferenceSystems(owner.referenceSystems);
         menu.addCopyOptions(view.statusBar);
@@ -148,12 +135,12 @@ final class CoverageControls extends ViewAndControls {
          * Put all sections together and have the first one expanded by 
default.
          * The "Properties" section will be built by `PropertyPaneCreator` 
only if requested.
          */
-        controls = new TitledPane[] {
+        final TitledPane deferred;                  // Control to be built 
only if requested.
+        controlPanes = new TitledPane[] {
             new TitledPane(vocabulary.getString(Vocabulary.Keys.Display),  
displayPane),
             new TitledPane(vocabulary.getString(Vocabulary.Keys.Isolines), 
isolinesPane),
-            new TitledPane(vocabulary.getString(Vocabulary.Keys.Properties), 
null)
+            deferred = new 
TitledPane(vocabulary.getString(Vocabulary.Keys.Properties), null)
         };
-        final TitledPane delayed = controls[2];     // Control to be built 
only if requested.
         /*
          * Set listeners: changes on `CoverageCanvas` properties are 
propagated to the corresponding
          * `CoverageExplorer` properties. This constructor does not install 
listeners in the opposite
@@ -161,7 +148,8 @@ final class CoverageControls extends ViewAndControls {
          */
         view.resourceProperty.addListener((p,o,n) -> onPropertySet(n, null));
         view.coverageProperty.addListener((p,o,n) -> 
onPropertySet(view.getResourceIfAdjusting(), n));
-        delayed.expandedProperty().addListener(new PropertyPaneCreator(view, 
delayed));
+        deferred.expandedProperty().addListener(new PropertyPaneCreator(view, 
deferred));
+        setView(view.getView(), view.statusBar);
     }
 
     /**
@@ -203,22 +191,4 @@ final class CoverageControls extends ViewAndControls {
         }
         view.setCoverage(resource, coverage);
     }
-
-    /**
-     * Returns the main component, which is showing coverage tabular data.
-     */
-    @Override
-    final Region view() {
-        return imageAndStatus;
-    }
-
-    /**
-     * Returns the controls for controlling the view of tabular data.
-     * This method does not clone the returned array; do not modify!
-     */
-    @Override
-    @SuppressWarnings("ReturnOfCollectionOrArrayField")
-    final TitledPane[] controlPanes() {
-        return controls;
-    }
 }
diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageExplorer.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageExplorer.java
index 6c08fc98bb..cbae6baefa 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageExplorer.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/CoverageExplorer.java
@@ -65,7 +65,7 @@ import org.apache.sis.gui.Widget;
  * implementation may generalize to {@link org.opengis.coverage.Coverage} 
instances.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.3
  *
  * @see CoverageCanvas
  * @see GridView
@@ -283,7 +283,6 @@ public class CoverageExplorer extends Widget {
                 case IMAGE: c = new CoverageControls(this); break;
                 default: throw new AssertionError(type);
             }
-            SplitPane.setResizableWithParent(c.view(), Boolean.TRUE);
             views.put(type, c);
             load = true;
         }
@@ -335,7 +334,7 @@ public class CoverageExplorer extends Widget {
             final View type = getViewType();
             final ViewAndControls c = getViewAndControls(type, false);
             group.selectToggle(group.getToggles().get(type.ordinal()));
-            content = new SplitPane(c.controls(), c.view());
+            content = new SplitPane(c.controls(), c.viewAndNavigation);
             ToolbarButton.insert(content, buttons);
             /*
              * The divider position is supposed to be a fraction between 0 and 
1. A value of 1 would mean
@@ -350,8 +349,9 @@ public class CoverageExplorer extends Widget {
     }
 
     /**
-     * Returns the region containing only the data visualization component, 
without controls.
-     * This is a {@link GridView} or {@link CoverageCanvas} together with 
their {@link StatusBar}.
+     * Returns the region containing the data visualization component, without 
controls other than navigation.
+     * This is a {@link GridView} or {@link CoverageCanvas} together with 
their {@link StatusBar}
+     * and navigation controls for selecting the slice in a 
<var>n</var>-dimensional data cube.
      * The {@link Region} subclass returned by this method is implementation 
dependent and may change
      * in any future version.
      *
@@ -361,7 +361,7 @@ public class CoverageExplorer extends Widget {
     public final Region getDataView(final View type) {
         assert Platform.isFxApplicationThread();
         ArgumentChecks.ensureNonNull("type", type);
-        return getViewAndControls(type, false).view();
+        return getViewAndControls(type, false).viewAndNavigation;
     }
 
     /**
@@ -374,7 +374,7 @@ public class CoverageExplorer extends Widget {
     public final TitledPane[] getControls(final View type) {
         assert Platform.isFxApplicationThread();
         ArgumentChecks.ensureNonNull("type", type);
-        return getViewAndControls(type, false).controlPanes().clone();
+        return getViewAndControls(type, false).controlPanes.clone();
     }
 
     /**
@@ -433,7 +433,7 @@ public class CoverageExplorer extends Widget {
     private void onViewTypeSet(final View type) {
         final ViewAndControls c = getViewAndControls(type, true);
         if (content != null) {
-            content.getItems().setAll(c.controls(), c.view());
+            content.getItems().setAll(c.controls(), c.viewAndNavigation);
             final Toggle selector = c.selector;
             if (selector != null) {
                 selector.setSelected(true);
diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/GridControls.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/GridControls.java
index 63a7c33d3f..99dcd22d36 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/GridControls.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/GridControls.java
@@ -22,7 +22,6 @@ import javafx.scene.control.Slider;
 import javafx.scene.control.TableView;
 import javafx.scene.control.TitledPane;
 import javafx.scene.layout.GridPane;
-import javafx.scene.layout.Region;
 import javafx.scene.layout.VBox;
 import org.apache.sis.storage.GridCoverageResource;
 import org.apache.sis.coverage.grid.GridCoverage;
@@ -37,7 +36,7 @@ import org.apache.sis.internal.gui.Styles;
  * The controls are updated when the image shown in {@link GridView} is 
changed.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.3
  * @since   1.1
  * @module
  */
@@ -47,11 +46,6 @@ final class GridControls extends ViewAndControls {
      */
     private final GridView view;
 
-    /**
-     * The controls for changing {@link #view}.
-     */
-    private final TitledPane[] controls;
-
     /**
      * The control showing sample dimensions for the current coverage.
      */
@@ -60,7 +54,7 @@ final class GridControls extends ViewAndControls {
     /**
      * Creates a new set of grid controls.
      *
-     * @param  owner  the widget which create this view. Can not be null.
+     * @param  owner  the widget which creates this view. Can not be null.
      */
     GridControls(final CoverageExplorer owner) {
         super(owner);
@@ -90,10 +84,11 @@ final class GridControls extends ViewAndControls {
         /*
          * All sections put together.
          */
-        controls = new TitledPane[] {
+        controlPanes = new TitledPane[] {
             new TitledPane(vocabulary.getString(Vocabulary.Keys.Display), 
displayPane)
             // TODO: more controls to be added in a future version.
         };
+        setView(view, view.statusBar);
     }
 
     /**
@@ -111,10 +106,10 @@ final class GridControls extends ViewAndControls {
      * Invoked after {@link GridView#setImage(ImageRequest)} for updating the 
table of sample
      * dimensions when information become available. This method is invoked in 
JavaFX thread.
      *
-     * @param  source  the new source of coverage, or {@code null} if none.
-     * @param  data    the new coverage, or {@code null} if none.
+     * @param  resource  the new source of coverage, or {@code null} if none.
+     * @param  data      the new coverage, or {@code null} if none.
      */
-    final void notifyDataChanged(final GridCoverageResource source, final 
GridCoverage data) {
+    final void notifyDataChanged(final GridCoverageResource resource, final 
GridCoverage data) {
         final ObservableList<SampleDimension> items = 
sampleDimensions.getItems();
         if (data != null) {
             items.setAll(data.getSampleDimensions());
@@ -122,7 +117,7 @@ final class GridControls extends ViewAndControls {
         } else {
             items.clear();
         }
-        owner.notifyDataChanged(source, data);
+        owner.notifyDataChanged(resource, data);
     }
 
     /**
@@ -136,22 +131,4 @@ final class GridControls extends ViewAndControls {
     final void load(final ImageRequest request) {
         view.setImage(request);
     }
-
-    /**
-     * Returns the main component, which is showing coverage tabular data.
-     */
-    @Override
-    final Region view() {
-        return view;
-    }
-
-    /**
-     * Returns the controls for controlling the view of tabular data.
-     * This method does not clone the returned array; do not modify!
-     */
-    @Override
-    @SuppressWarnings("ReturnOfCollectionOrArrayField")
-    final TitledPane[] controlPanes() {
-        return controls;
-    }
 }
diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/GridViewSkin.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/GridViewSkin.java
index a2c64d616a..00220a5de4 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/GridViewSkin.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/GridViewSkin.java
@@ -27,7 +27,6 @@ import javafx.scene.Cursor;
 import javafx.scene.control.ScrollBar;
 import javafx.scene.control.skin.VirtualFlow;
 import javafx.scene.control.skin.VirtualContainerBase;
-import javafx.scene.layout.Region;
 import javafx.scene.layout.HBox;
 import javafx.scene.paint.Color;
 import javafx.scene.shape.Rectangle;
@@ -56,7 +55,7 @@ import org.apache.sis.internal.gui.Styles;
  * </ul>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.3
  * @since   1.1
  * @module
  */
@@ -198,14 +197,9 @@ final class GridViewSkin extends 
VirtualContainerBase<GridView, GridRow> impleme
         /*
          * The list of children is initially empty. We need to add the virtual 
flow
          * (together with headers, selection, etc.), otherwise nothing will 
appear.
-         * The status bar is declared unmanaged for avoiding relayout of the 
whole
-         * widget every time that coordinates are formatted. This is okay 
because
-         * the `layoutChildren(…)` method in this class does layout itself.
          */
-        final Region bar = view.statusBar.getView();
-        bar.setManaged(false);
         getChildren().addAll(topBackground, leftBackground, selectedColumn,
-                             selectedRow, headerRow, selection, bar, flow);
+                             selectedRow, headerRow, selection, flow);
         /*
          * Keyboard and drag events for moving the viewed bounds.
          */
@@ -547,9 +541,8 @@ final class GridViewSkin extends 
VirtualContainerBase<GridView, GridRow> impleme
         final Flow   flow         = (Flow) getVirtualFlow();
         final double cellHeight   = flow.getFixedCellSize();
         final double headerHeight = cellHeight + 2*cellSpacing;
-        final double statusHeight = view.statusBar.getView().getHeight();
         final double dataY        = y + headerHeight;
-        final double dataHeight   = height - headerHeight - statusHeight;
+        final double dataHeight   = height - headerHeight;
         layoutAll |= (flow.getWidth() != width) || (flow.getHeight() != 
dataHeight);
         flow.resizeRelocate(x, dataY, width, dataHeight);
         /*
@@ -596,8 +589,6 @@ final class GridViewSkin extends 
VirtualContainerBase<GridView, GridRow> impleme
         if (layoutAll || oldPos != leftPosition) {
             layoutInArea(headerRow, x, y, width, headerHeight,
                          Node.BASELINE_OFFSET_SAME_AS_HEIGHT, HPos.LEFT, 
VPos.TOP);
-            layoutInArea(view.statusBar.getView(), x, height - statusHeight, 
width, statusHeight,
-                         Node.BASELINE_OFFSET_SAME_AS_HEIGHT, HPos.RIGHT, 
VPos.BOTTOM);
             final ObservableList<Node> children = headerRow.getChildren();
             final int count   = children.size();
             final int missing = (int) Math.ceil((width - headerWidth) / 
cellWidth) - count;
diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/ViewAndControls.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/ViewAndControls.java
index 1e396da764..0d30ed39f9 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/ViewAndControls.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/coverage/ViewAndControls.java
@@ -23,12 +23,15 @@ import javafx.scene.control.Toggle;
 import javafx.scene.control.TitledPane;
 import javafx.scene.control.Accordion;
 import javafx.scene.control.SplitPane;
+import javafx.scene.layout.Priority;
 import javafx.scene.layout.Region;
+import javafx.scene.layout.VBox;
 import javafx.scene.text.Font;
 import javafx.scene.text.FontWeight;
 import org.apache.sis.internal.gui.Styles;
 import org.apache.sis.storage.Resource;
 import org.apache.sis.coverage.grid.GridCoverage;
+import org.apache.sis.gui.map.StatusBar;
 import org.apache.sis.util.resources.IndexedResourceBundle;
 
 
@@ -40,7 +43,7 @@ import org.apache.sis.util.resources.IndexedResourceBundle;
  * mechanisms are implemented in the view (different views may load a 
different amount of data).
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.3
  * @since   1.1
  * @module
  */
@@ -68,7 +71,20 @@ abstract class ViewAndControls {
     Toggle selector;
 
     /**
-     * The controls put together in an accordion. Built only if requested
+     * The main component which is showing coverage data or image together 
with status bar.
+     * This is the component to show on the right (largest) part of the split 
pane.
+     */
+    final VBox viewAndNavigation;
+
+    /**
+     * The panes for controlling the view, set by subclass constructors and 
unmodified after construction.
+     * Those panes are the components to show on the left (smaller) part of 
the split pane.
+     * Callers will typically put those components in an {@link Accordion}.
+     */
+    TitledPane[] controlPanes;
+
+    /**
+     * The {@link #controlPanes} put together in an accordion. Built only if 
requested
      * (may never be requested if the caller creates its own accordion with 
additional panes,
      * as {@link org.apache.sis.gui.dataset.ResourceExplorer} does).
      *
@@ -81,9 +97,9 @@ abstract class ViewAndControls {
      * Subclasses should define the following method:
      *
      * {@preformat java
-     *     private void coverageChanged(final Resource source, final 
GridCoverage data) {
+     *     private void onPropertySet(final Resource resource, final 
GridCoverage data) {
      *         // Update subclass-specific controls here, before to forward to 
explorer.
-     *         owner.coverageChanged(source, data);
+     *         owner.notifyDataChanged(resource, data);
      *     }
      * }
      */
@@ -92,12 +108,53 @@ abstract class ViewAndControls {
     /**
      * Creates a new view-control pair.
      *
-     * @param  owner  the widget which create this view. Can not be null.
+     * @param  owner  the widget which creates this view. Can not be null.
      */
-    ViewAndControls(final CoverageExplorer owner) {
+    protected ViewAndControls(final CoverageExplorer owner) {
         this.owner = owner;
+        viewAndNavigation = new VBox();
+    }
+
+    /**
+     * Invoked by subclass constructors for declaring the main visual 
component.
+     * The given component will be added to the {@link #viewAndNavigation} 
node.
+     */
+    final void setView(final Region view, final StatusBar status) {
+        final Region bar = status.getView();
+        VBox.setVgrow(view, Priority.ALWAYS);
+        VBox.setVgrow(bar,  Priority.NEVER);
+        viewAndNavigation.getChildren().setAll(view, bar);
+        SplitPane.setResizableWithParent(viewAndNavigation, Boolean.TRUE);
+    }
+
+    /**
+     * Returns the controls for controlling the view.
+     * This is the component to show on the left (smaller) part of the split 
pane.
+     */
+    final Accordion controls() {
+        if (controls == null) {
+            final TitledPane[] panes = controlPanes;
+            controls = new Accordion(panes);
+            controls.setExpandedPane(panes[0]);
+            SplitPane.setResizableWithParent(controls, Boolean.FALSE);
+        }
+        return controls;
     }
 
+    /**
+     * Sets the view content to the given resource, coverage or image.
+     * This method is invoked when a new source of data (either a resource or 
a coverage) is specified,
+     * or when a previously hidden view is made visible. Implementations may 
start a background thread.
+     *
+     * @param  request  the resource, coverage or image to set, or {@code 
null} for clearing the view.
+     */
+    abstract void load(ImageRequest request);
+
+
+
+
+    // ════════ Helper methods for subclass constructors 
════════════════════════════════════════════════════════
+
     /**
      * Creates a label with the specified text (fetched from localized 
resources) associated to the given control.
      * If the given control is {@code null}, then this method returns {@code 
null} for skipping the row completely.
@@ -140,42 +197,4 @@ abstract class ViewAndControls {
     private static Font fontOfGroup() {
         return Font.font(null, FontWeight.BOLD, -1);
     }
-
-    /**
-     * Returns the main component, which is showing coverage data or image.
-     * This is the component to show on the right (largest) part of the split 
pane.
-     */
-    abstract Region view();
-
-    /**
-     * Returns the list of control panels for controlling the view.
-     * They are the components to show on the left (smaller) part of the split 
pane.
-     * Callers will typically put those components in an {@link 
javafx.scene.control.Accordion}.
-     *
-     * @return the controls. This method does not clone the returned array; do 
not modify!
-     */
-    abstract TitledPane[] controlPanes();
-
-    /**
-     * Returns the controls for controlling the view.
-     * This is the component to show on the left (smaller) part of the split 
pane.
-     */
-    final Accordion controls() {
-        if (controls == null) {
-            final TitledPane[] panes = controlPanes();
-            controls = new Accordion(panes);
-            controls.setExpandedPane(panes[0]);
-            SplitPane.setResizableWithParent(controls, Boolean.FALSE);
-        }
-        return controls;
-    }
-
-    /**
-     * Sets the view content to the given resource, coverage or image.
-     * This method is invoked when a new source of data (either a resource or 
a coverage) is specified,
-     * or when a previously hidden view is made visible. Implementations may 
start a background thread.
-     *
-     * @param  request  the resource, coverage or image to set, or {@code 
null} for clearing the view.
-     */
-    abstract void load(ImageRequest request);
 }
diff --git 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ResourceExplorer.java
 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ResourceExplorer.java
index 162832772f..3f09fd1fb9 100644
--- 
a/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ResourceExplorer.java
+++ 
b/application/sis-javafx/src/main/java/org/apache/sis/gui/dataset/ResourceExplorer.java
@@ -181,6 +181,7 @@ public class ResourceExplorer extends WindowManager {
         final TitledPane resourcesPane = new 
TitledPane(vocabulary.getString(Vocabulary.Keys.Resources), resources);
         controls = new Accordion(resourcesPane);
         controls.setExpandedPane(resourcesPane);
+        SplitPane.setResizableWithParent(controls, Boolean.FALSE);
         expandedPane = new EnumMap<>(CoverageExplorer.View.class);
         /*
          * "Summary" tab showing a summary of resource metadata.
@@ -223,7 +224,7 @@ public class ResourceExplorer extends WindowManager {
         tabs.setTabClosingPolicy(TabPane.TabClosingPolicy.UNAVAILABLE);
         tabs.setTabDragPolicy(TabPane.TabDragPolicy.REORDER);
         content = new SplitPane(controls, tabs);
-        content.setDividerPosition(0, 0.2);
+        content.setDividerPosition(0, 1./3);
         SplitPane.setResizableWithParent(resources, Boolean.FALSE);
         SplitPane.setResizableWithParent(tabs, Boolean.TRUE);
         /*

Reply via email to