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);
/*