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 b729668 Fix a problem at initialization of CRS choices (was
initialized to the wrong CRS).
b729668 is described below
commit b72966864487dcacaf1471b1324c639037966114
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Fri Apr 24 19:36:52 2020 +0200
Fix a problem at initialization of CRS choices (was initialized to the
wrong CRS).
---
.../java/org/apache/sis/gui/map/StatusBar.java | 42 ++++++++++---------
.../org/apache/sis/gui/referencing/MenuSync.java | 48 +++++++++++++++++-----
.../gui/referencing/RecentReferenceSystems.java | 38 +++++++++--------
3 files changed, 82 insertions(+), 46 deletions(-)
diff --git
a/application/sis-javafx/src/main/java/org/apache/sis/gui/map/StatusBar.java
b/application/sis-javafx/src/main/java/org/apache/sis/gui/map/StatusBar.java
index 8e053cb..3cf8192 100644
--- a/application/sis-javafx/src/main/java/org/apache/sis/gui/map/StatusBar.java
+++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/map/StatusBar.java
@@ -29,6 +29,7 @@ import javafx.scene.layout.Priority;
import javafx.scene.control.Label;
import javafx.scene.control.Button;
import javafx.scene.control.Tooltip;
+import javafx.scene.control.Menu;
import javafx.scene.control.ContextMenu;
import javafx.scene.input.MouseEvent;
import javafx.scene.text.TextAlignment;
@@ -275,9 +276,9 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
* If the {@code choices} argument is non-null, user will be able to
select different CRS
* using the contextual menu on the status bar.
*
- * @param choices the manager of reference systems chosen by user, or
{@code null} if none.
+ * @param systemChooser the manager of reference systems chosen by user,
or {@code null} if none.
*/
- public StatusBar(final RecentReferenceSystems choices) {
+ public StatusBar(final RecentReferenceSystems systemChooser) {
localToObjectiveCRS = MathTransforms.identity(BIDIMENSIONAL);
localToFormatCRS = localToObjectiveCRS;
targetCoordinates = new GeneralDirectPosition(BIDIMENSIONAL);
@@ -297,12 +298,15 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
position.setTextAlignment(TextAlignment.RIGHT);
canvasProperty = new SimpleObjectProperty<>(this, "canvas");
canvasProperty.addListener(this::onCanvasSpecified);
- if (choices == null) {
+ if (systemChooser == null) {
areaOfInterest = null;
} else {
- areaOfInterest = choices.areaOfInterest;
- final ContextMenu menu = new
ContextMenu(choices.createMenuItems(this::onSelectCRS));
- view.setOnMousePressed((MouseEvent event) -> {
+ areaOfInterest = systemChooser.areaOfInterest;
+ final Menu choices = systemChooser.createMenuItems((property,
oldValue, newValue) -> {
+ findFormatOperation(newValue instanceof
CoordinateReferenceSystem ? (CoordinateReferenceSystem) newValue : null);
+ });
+ final ContextMenu menu = new ContextMenu(choices);
+ view.setOnMousePressed((event) -> {
if (event.isSecondaryButtonDown()) {
menu.show((HBox) event.getSource(), event.getScreenX(),
event.getScreenY());
} else {
@@ -607,6 +611,19 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
}
});
} else {
+ /*
+ * If the requested CRS is the objective CRS, avoid above costly
operation.
+ * The work that we need to do is to cancel the effect of
`localToFormatCRS`.
+ * As a special case if `objectiveCRS` was unknown before this
method call,
+ * set it to the given value. This is needed for initializing the
format CRS
+ * to the first reference system listed in
`RecentReferenceSystems` choices.
+ * We could not do this work at construction time because the CRS
choices may
+ * be computed in a background thread, in which case it became
known only a
+ * little bit later and given to `StatusBar` through listeners.
+ */
+ if (objectiveCRS == null) {
+ objectiveCRS = crs;
+ }
position.setMinWidth(0);
resetFormatCRS(Styles.NORMAL_TEXT);
}
@@ -920,19 +937,6 @@ public class StatusBar extends Widget implements
EventHandler<MouseEvent> {
}
/**
- * Invoked when the user selects a new reference system for the
coordinates to show in status bar.
- *
- * @param property the {@link org.apache.sis.gui.referencing.MenuSync}
property.
- * @param oldValue the old reference system, or {@code null} if none.
- * @param newValue the CRS to use for formatting coordinates in this
status bar.
- */
- private void onSelectCRS(ObservableValue<? extends ReferenceSystem>
property,
- ReferenceSystem oldValue, ReferenceSystem
newValue)
- {
- findFormatOperation(newValue instanceof CoordinateReferenceSystem ?
(CoordinateReferenceSystem) newValue : null);
- }
-
- /**
* Returns the error message currently shown.
*
* @return the current error message, or an empty value if none.
diff --git
a/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/MenuSync.java
b/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/MenuSync.java
index a51c018..f25f675 100644
---
a/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/MenuSync.java
+++
b/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/MenuSync.java
@@ -19,7 +19,6 @@ package org.apache.sis.gui.referencing;
import java.util.Arrays;
import java.util.IdentityHashMap;
import java.util.Iterator;
-import java.util.List;
import java.util.Map;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
@@ -86,8 +85,7 @@ final class MenuSync extends
SimpleObjectProperty<ReferenceSystem> implements Ev
* @param bean the menu to keep synchronized with the list of
reference systems.
* @param action the user-specified action to execute when a reference
system is selected.
*/
- @SuppressWarnings("ThisEscapedInObjectConstruction") // `this` is
last and this class is final.
- MenuSync(final RecentReferenceSystems owner, final List<ReferenceSystem>
systems,
+ MenuSync(final RecentReferenceSystems owner, final
ObservableList<ReferenceSystem> systems,
final Menu bean, final ChangeListener<ReferenceSystem> action)
{
super(bean, "value");
@@ -95,11 +93,31 @@ final class MenuSync extends
SimpleObjectProperty<ReferenceSystem> implements Ev
this.menus = bean.getItems();
this.group = new ToggleGroup();
this.action = action;
+ /*
+ * We do not register listener for `systems` list.
+ * Instead `notifyChanges(…)` will be invoked directly by
RecentReferenceSystems.
+ */
final MenuItem[] items = new MenuItem[systems.size()];
for (int i=0; i<items.length; i++) {
items[i] = createItem(systems.get(i));
}
menus.setAll(items);
+ initialize(systems);
+ }
+
+ /**
+ * Sets the initial value to the first item in the {@code systems} list,
if any.
+ * This method is invoked in JavaFX thread at construction time or, if it
didn't
+ * work at some later time when the systems list may contain an element.
+ * This method should not be invoked anymore after initialization
succeeded.
+ */
+ private void initialize(final ObservableList<? extends ReferenceSystem>
systems) {
+ for (final ReferenceSystem system : systems) {
+ if (system != RecentReferenceSystems.OTHER) {
+ set(system);
+ break;
+ }
+ }
}
/**
@@ -176,6 +194,12 @@ final class MenuSync extends
SimpleObjectProperty<ReferenceSystem> implements Ev
dispose(recycle.next());
}
GUIUtilities.copyAsDiff(Arrays.asList(items), menus);
+ /*
+ * If we had no previously selected item, selects it now.
+ */
+ if (get() == null) {
+ initialize(systems);
+ }
}
/**
@@ -191,7 +215,6 @@ final class MenuSync extends
SimpleObjectProperty<ReferenceSystem> implements Ev
// ClassCastException should not happen because this listener is
registered only on MenuItem.
final Object value = ((MenuItem)
event.getSource()).getProperties().get(REFERENCE_SYSTEM_KEY);
ReferenceSystem crs = (value == CHOOSER) ?
RecentReferenceSystems.OTHER : (ReferenceSystem) value;
- action.changed(this, get(), crs);
if (crs != RecentReferenceSystems.OTHER) {
set(crs);
}
@@ -203,13 +226,18 @@ final class MenuSync extends
SimpleObjectProperty<ReferenceSystem> implements Ev
*/
@Override
public void set(final ReferenceSystem system) {
- super.set(system);
- for (final MenuItem item : menus) {
- if (item instanceof RadioMenuItem &&
item.getProperties().get(REFERENCE_SYSTEM_KEY) == system) {
- ((RadioMenuItem) item).setSelected(true);
- return;
+ final ReferenceSystem old = get();
+ if (old != system) {
+ super.set(system);
+ for (final MenuItem item : menus) {
+ if (item instanceof RadioMenuItem &&
item.getProperties().get(REFERENCE_SYSTEM_KEY) == system) {
+ ((RadioMenuItem) item).setSelected(true);
+ action.changed(this, old, system);
+ return;
+ }
}
+ group.selectToggle(null);
+ action.changed(this, old, null);
}
- group.selectToggle(null);
}
}
diff --git
a/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/RecentReferenceSystems.java
b/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/RecentReferenceSystems.java
index 6355f7a..f6ae41d 100644
---
a/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/RecentReferenceSystems.java
+++
b/application/sis-javafx/src/main/java/org/apache/sis/gui/referencing/RecentReferenceSystems.java
@@ -524,20 +524,19 @@ public class RecentReferenceSystems {
* {@code systems} list has been computed.
*/
private void setReferenceSystems(final List<ReferenceSystem> systems,
final ComparisonMode mode) {
- if (systems != null) {
+ if (systems != null) try {
+ isAdjusting = true;
/*
- * The call to `copyAsDiff(…)` may cause `ChoiceBox` values to be
lost if the corresponding item
- * in the `referenceSystems` list is temporarily removed (before
to be inserted elsewhere).
- * Save the values before to modify the list.
+ * The call to `copyAsDiff(…)` may cause some ChoiceBox values to
be lost if the corresponding
+ * item in the `referenceSystems` list is temporarily removed
before to be inserted elsewhere.
+ * Save the values before to modify the list. Note that if
`referenceSystems` was empty before
+ * the copy, `controlValues` should be null before the copy but
may become non-null after the
+ * copy because listeners will have initialized them to the first
`ReferenceSystem` available.
+ * Those non-null values will not be reflected in the `values`
array, so we should ignore them.
*/
final ReferenceSystem[] values =
controlValues.stream().map(WritableValue::getValue).toArray(ReferenceSystem[]::new);
- try {
- isAdjusting = true;
- if (GUIUtilities.copyAsDiff(systems, referenceSystems)) {
- notifyChanges();
- }
- } finally {
- isAdjusting = false;
+ if (GUIUtilities.copyAsDiff(systems, referenceSystems)) {
+ notifyChanges();
}
/*
* Restore the previous selections. This code also serves another
purpose: the previous selection
@@ -549,15 +548,19 @@ public class RecentReferenceSystems {
final int n = referenceSystems.size();
for (int j=0; j<values.length; j++) {
ReferenceSystem system = values[j];
- for (int i=0; i<n; i++) {
- final ReferenceSystem candidate = referenceSystems.get(i);
- if (Utilities.deepEquals(candidate, system, mode)) {
- system = candidate;
- break;
+ if (system != null) { // See comment about
empty `referenceSystems` list.
+ for (int i=0; i<n; i++) {
+ final ReferenceSystem candidate =
referenceSystems.get(i);
+ if (Utilities.deepEquals(candidate, system, mode)) {
+ system = candidate;
+ break;
+ }
}
+ controlValues.get(j).setValue(system);
}
- controlValues.get(j).setValue(system);
}
+ } finally {
+ isAdjusting = false;
}
}
@@ -581,6 +584,7 @@ public class RecentReferenceSystems {
final ReferenceSystem oldValue,
ReferenceSystem newValue)
{
if (isAdjusting) {
+ action.changed(property, oldValue, newValue);
return;
}
if (newValue == OTHER) {