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.
          */

Reply via email to