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 c778d9a0d5606cbe5611b72653d6380a287f6ade Author: Martin Desruisseaux <[email protected]> AuthorDate: Wed Jun 29 00:02:22 2022 +0200 Add visual separators. --- .../java/org/apache/sis/gui/map/StatusBar.java | 17 +++++- .../org/apache/sis/gui/referencing/MenuSync.java | 67 +++++++++++++--------- 2 files changed, 53 insertions(+), 31 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 5050a22ab1..7e62bffa90 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 javax.measure.Unit; import javafx.geometry.Pos; import javafx.geometry.Insets; import javafx.geometry.Point2D; +import javafx.geometry.Orientation; import javafx.scene.Node; import javafx.scene.paint.Color; import javafx.scene.layout.HBox; @@ -41,6 +42,7 @@ import javafx.scene.control.Tooltip; import javafx.scene.control.Menu; import javafx.scene.control.MenuItem; import javafx.scene.control.ContextMenu; +import javafx.scene.control.Separator; import javafx.scene.input.MouseEvent; import javafx.scene.text.TextAlignment; import javafx.event.EventHandler; @@ -147,6 +149,7 @@ public class StatusBar extends Widget implements EventHandler<MouseEvent> { /** * The container of controls making the status bar. + * Contains {@link #message}, {@link #position} and {@link #sampleValues}. * * @see #getView() */ @@ -494,7 +497,7 @@ public class StatusBar extends Widget implements EventHandler<MouseEvent> { position.setAlignment(Pos.CENTER_RIGHT); position.setTextAlignment(TextAlignment.RIGHT); - view = new HBox(18, message, position); + view = new HBox(6, message, position); view.setPadding(PADDING); view.setAlignment(Pos.CENTER_RIGHT); /* @@ -1545,11 +1548,19 @@ public class StatusBar extends Widget implements EventHandler<MouseEvent> { sampleValues.setMaxWidth(Label.USE_PREF_SIZE); } if (c.lastIndexOf(sampleValues) < 0) { - c.add(sampleValues); + final Separator separator = new Separator(Orientation.VERTICAL); + c.addAll(separator, sampleValues); } } else if (sampleValues != null) { sampleValues.setText(null); - c.remove(sampleValues); + int i = c.lastIndexOf(sampleValues); + if (i >= 0) { + c.remove(i); + if (--i >= 0) { + final Node last = c.remove(i); + assert last instanceof Separator : last; + } + } } isSampleValuesVisible = visible; } 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 ee9b479a97..41bb226624 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 @@ -17,12 +17,10 @@ package org.apache.sis.gui.referencing; import java.util.List; -import java.util.Arrays; import java.util.ArrayList; import java.util.IdentityHashMap; import java.util.Iterator; import java.util.Locale; -import java.util.Map; import javafx.beans.property.SimpleObjectProperty; import javafx.collections.ObservableList; import javafx.event.ActionEvent; @@ -30,6 +28,7 @@ import javafx.event.EventHandler; import javafx.scene.control.Menu; import javafx.scene.control.MenuItem; import javafx.scene.control.RadioMenuItem; +import javafx.scene.control.SeparatorMenuItem; import javafx.scene.control.ToggleGroup; import org.opengis.referencing.ReferenceSystem; import org.opengis.referencing.crs.DerivedCRS; @@ -134,10 +133,13 @@ final class MenuSync extends SimpleObjectProperty<ReferenceSystem> implements Ev /* * Root menu. The list of recent reference system is dynamic and will change according user actions. */ - final MenuItem[] items = new MenuItem[systems.size()]; + final List<MenuItem> items = new ArrayList<>(systems.size() + 1); final Locale locale = action.owner().locale; - for (int i=0; i<items.length; i++) { - items[i] = createItem(systems.get(i), locale); + for (final ReferenceSystem system : systems) { + if (system == RecentReferenceSystems.OTHER) { + items.add(new SeparatorMenuItem()); + } + items.add(createItem(system, locale)); } rootMenus.addAll(items); initialize(); @@ -248,9 +250,11 @@ final class MenuSync extends SimpleObjectProperty<ReferenceSystem> implements Ev * Must be invoked after removing a menu item for avoiding memory leak. */ private static void dispose(final MenuItem item) { - item.setOnAction(null); - if (item instanceof RadioMenuItem) { - ((RadioMenuItem) item).setToggleGroup(null); + if (item != null) { + item.setOnAction(null); + if (item instanceof RadioMenuItem) { + ((RadioMenuItem) item).setToggleGroup(null); + } } } @@ -265,12 +269,15 @@ final class MenuSync extends SimpleObjectProperty<ReferenceSystem> implements Ev /* * Build a map of current menu items. Key are CRS objects. */ - final var subMenus = new ArrayList<Menu>(); - final Map<Object,MenuItem> mapping = new IdentityHashMap<>(); + SeparatorMenuItem separator = null; + final var subMenus = new ArrayList<Menu>(2); + final var mapping = new IdentityHashMap<Object,MenuItem>(10); for (final Iterator<MenuItem> it = rootMenus.iterator(); it.hasNext();) { final MenuItem item = it.next(); if (item instanceof Menu) { subMenus.add((Menu) item); + } else if (item instanceof SeparatorMenuItem) { + separator = (SeparatorMenuItem) item; // Should have only one. } else if (mapping.putIfAbsent(item.getProperties().get(REFERENCE_SYSTEM_KEY), item) != null) { it.remove(); // Remove duplicated item. Should never happen, but we are paranoiac. dispose(item); @@ -282,12 +289,12 @@ final class MenuSync extends SimpleObjectProperty<ReferenceSystem> implements Ev * loop, the map will contain only menu items for CRS that are no longer in the list of CRS to offer. */ final int newCount = recentSystems.size(); - final MenuItem[] items = new MenuItem[newCount + subMenus.size()]; - for (int i=0; i<newCount; i++) { - Object key = recentSystems.get(i); + final var items = new ArrayList<MenuItem>(newCount + 4); + for (Object key : recentSystems) { if (key == RecentReferenceSystems.OTHER) key = CHOOSER; - items[i] = mapping.remove(key); + items.add(mapping.remove(key)); // May be null. } + dispose(mapping.remove(CHOOSER)); // Safety for avoiding AssertionError in block below. /* * Previous loop took all items that could be reused as-is. Now search for all items that are new. * For each new item to create, recycle an arbitrary `mapping` element (in any order) if some exist. @@ -297,38 +304,42 @@ final class MenuSync extends SimpleObjectProperty<ReferenceSystem> implements Ev final Iterator<MenuItem> recycle = mapping.values().iterator(); final Locale locale = action.owner().locale; for (int i=0; i<newCount; i++) { - if (items[i] == null) { - MenuItem item = null; + if (items.get(i) == null) { + final MenuItem item; final ReferenceSystem system = recentSystems.get(i); if (system != RecentReferenceSystems.OTHER && recycle.hasNext()) { item = recycle.next(); - recycle.remove(); - if (item instanceof RadioMenuItem) { - item.setText(IdentifiedObjects.getDisplayName(system, locale)); - item.getProperties().put(REFERENCE_SYSTEM_KEY, system); - } - } - if (item == null) { + assert item instanceof RadioMenuItem : item; + item.setText(IdentifiedObjects.getDisplayName(system, locale)); + item.getProperties().put(REFERENCE_SYSTEM_KEY, system); + } else { item = createItem(system, locale); } if (selected != null && system == selected) { ((RadioMenuItem) item).setSelected(true); // ClassCastException should never occur here. selected = null; } - items[i] = item; + items.set(i, item); } } /* * If there is any item left, we must remove them from the ToggleGroup for avoiding memory leak. - * The sub-menus (if any) are appended last with no change. + * Add separator before "Other…" item. The sub-menus (if any) are appended last with no change. */ while (recycle.hasNext()) { dispose(recycle.next()); } - for (int i=newCount; i<items.length; i++) { - items[i] = subMenus.get(i - newCount); + for (int i = items.size(); --i >= 0;) { + if (items.get(i).getClass() == MenuItem.class) { + if (separator == null) { + separator = new SeparatorMenuItem(); + } + items.add(i, separator); + break; + } } - GUIUtilities.copyAsDiff(Arrays.asList(items), rootMenus); + items.addAll(subMenus); + GUIUtilities.copyAsDiff(items, rootMenus); /* * If we had no previously selected item, selects it now. */
