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 15f3a2904699439cfeac8bd6e6c59d2acf13c4e1 Author: Martin Desruisseaux <[email protected]> AuthorDate: Fri Sep 12 19:27:31 2025 +0200 Regression fix: bad handling of events in the JavaFX application blocked control on the color ramp. --- .../org/apache/sis/gui/controls/ColorCell.java | 2 +- .../sis/gui/controls/ColorColumnHandler.java | 2 +- .../org/apache/sis/gui/controls/ColorRamp.java | 2 +- .../org/apache/sis/gui/controls/TabularWidget.java | 8 +-- .../apache/sis/gui/coverage/CoverageStyling.java | 73 ++++++++++++++-------- 5 files changed, 54 insertions(+), 33 deletions(-) diff --git a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/controls/ColorCell.java b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/controls/ColorCell.java index c7b450bf65..96f191088f 100644 --- a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/controls/ColorCell.java +++ b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/controls/ColorCell.java @@ -229,7 +229,7 @@ final class ColorCell<S> extends TableCell<S,ColorRamp> implements EventHandler< * @see #setColorItem(ColorRamp) */ private Rectangle createRectangle(final double adjust) { - final Rectangle gr = new Rectangle(); + final var gr = new Rectangle(); gr.setHeight(HEIGHT); gr.widthProperty().bind(widthProperty().add(adjust)); return gr; diff --git a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/controls/ColorColumnHandler.java b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/controls/ColorColumnHandler.java index 2b1bb1493e..186a1a6bce 100644 --- a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/controls/ColorColumnHandler.java +++ b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/controls/ColorColumnHandler.java @@ -86,7 +86,7 @@ public abstract class ColorColumnHandler<S> implements Callback<TableColumn.Cell * The use of singular or plural depends on whether the column allows color gradients. */ protected final void addColumnTo(final TableView<S> table, final String header) { - final TableColumn<S,ColorRamp> colors = new TableColumn<>(header); + final var colors = new TableColumn<S,ColorRamp>(header); colors.setCellFactory((column) -> new ColorCell<S>(this)); colors.setCellValueFactory(this); colors.setSortable(false); diff --git a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/controls/ColorRamp.java b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/controls/ColorRamp.java index 74d4b5d75f..49f1fcb797 100644 --- a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/controls/ColorRamp.java +++ b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/controls/ColorRamp.java @@ -251,7 +251,7 @@ public final class ColorRamp { @Override public boolean equals(final Object obj) { if (obj instanceof ColorRamp) { - final ColorRamp other = (ColorRamp) obj; + final var other = (ColorRamp) obj; if (Arrays.equals(colors, other.colors)) { return (colors != null) || Objects.equals(name, other.name); } diff --git a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/controls/TabularWidget.java b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/controls/TabularWidget.java index 0843a18e3d..235e352e43 100644 --- a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/controls/TabularWidget.java +++ b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/controls/TabularWidget.java @@ -57,17 +57,17 @@ abstract class TabularWidget extends Widget { } /** - * Creates a new column for a boolean value represented by a checkbox. + * Creates a new column for a Boolean value represented by a checkbox. * * @param <S> the type of objects contained within the {@link TableView} items list. * @param header column header. - * @param factory link to the boolean property. + * @param factory link to the Boolean property. * @return a column for checkbox. */ static <S> TableColumn<S,Boolean> newBooleanColumn(final String header, final Callback<CellDataFeatures<S,Boolean>, ObservableValue<Boolean>> factory) { - final TableColumn<S,Boolean> c = new TableColumn<>(header); + final var c = new TableColumn<S,Boolean>(header); c.setCellFactory(CheckBoxTableCell.forTableColumn(c)); c.setCellValueFactory(factory); c.setSortable(false); @@ -88,7 +88,7 @@ abstract class TabularWidget extends Widget { static <S> TableColumn<S,String> newStringColumn(final String header, final Callback<CellDataFeatures<S,String>, ObservableValue<String>> factory) { - final TableColumn<S,String> c = new TableColumn<>(header); + final var c = new TableColumn<S,String>(header); c.setCellFactory(TextFieldTableCell.forTableColumn()); c.setCellValueFactory(factory); return c; diff --git a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/CoverageStyling.java b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/CoverageStyling.java index 6841dd17dc..0b52887686 100644 --- a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/CoverageStyling.java +++ b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/coverage/CoverageStyling.java @@ -30,6 +30,8 @@ import javafx.scene.control.MenuItem; import javafx.scene.control.ContextMenu; import javafx.collections.ObservableList; import javafx.beans.value.ObservableValue; +import javafx.beans.value.ChangeListener; +import javafx.beans.property.SimpleObjectProperty; import org.opengis.util.InternationalString; import org.apache.sis.coverage.Category; import org.apache.sis.image.Colorizer; @@ -48,13 +50,15 @@ import org.apache.sis.util.resources.Vocabulary; * * @author Martin Desruisseaux (Geomatys) */ -final class CoverageStyling extends ColorColumnHandler<Category> implements Function<Category,Color[]> { +final class CoverageStyling extends ColorColumnHandler<Category> + implements Function<Category, Color[]>, ChangeListener<ColorRamp> +{ /** * Customized colors selected by user. Keys are English names of categories. * * @see #apply(Category) */ - private final Map<String,ColorRamp> customizedColors; + private final Map<String, SimpleObjectProperty<ColorRamp>> customizedColors; /** * The view to notify when a color changed, or {@code null} if none. @@ -77,7 +81,11 @@ final class CoverageStyling extends ColorColumnHandler<Category> implements Func * This is used when the user clicks on "New window" button. */ final void copyStyling(final CoverageStyling source) { - customizedColors.putAll(source.customizedColors); + for (Map.Entry<String, SimpleObjectProperty<ColorRamp>> entry : source.customizedColors.entrySet()) { + final var property = new SimpleObjectProperty<>(entry.getValue().getValue()); + customizedColors.put(entry.getKey(), property); + property.addListener(this); + } if (canvas != null) { canvas.stylingChanged(); } @@ -109,18 +117,28 @@ final class CoverageStyling extends ColorColumnHandler<Category> implements Func * Returns the colors to apply for the given category as an observable value. * * @param row the row item for which to get color to show in color cell. Never {@code null}. - * @return the color(s) to use for the given row, or {@code null} if none (transparent). + * @return the color(s) to use for the given row. A property value of {@code null} means transparent. */ @Override - protected ObservableValue<ColorRamp> getObservableValue(final Category category) { - ColorRamp ramp = customizedColors.get(key(category)); - if (ramp == null) { - if (!category.isQuantitative()) { - return null; + protected SimpleObjectProperty<ColorRamp> getObservableValue(final Category category) { + return customizedColors.computeIfAbsent(key(category), (key) -> { + final var property = new SimpleObjectProperty<ColorRamp>(); + if (category.isQuantitative()) { + property.setValue(ColorRamp.DEFAULT); } - ramp = ColorRamp.DEFAULT; + property.addListener(this); + return property; + }); + } + + /** + * Invoked when the colors have changed. This method notifies the canvas that it needs to repaint itself. + */ + @Override + public void changed(ObservableValue<? extends ColorRamp> property, ColorRamp old, ColorRamp colors) { + if (canvas != null && !Objects.equals(colors, old)) { + canvas.stylingChanged(); } - return new ImmutableObjectProperty<>(ramp); } /** @@ -133,15 +151,18 @@ final class CoverageStyling extends ColorColumnHandler<Category> implements Func */ @Override public Color[] apply(final Category category) { - final ColorRamp ramp = customizedColors.get(key(category)); - if (ramp != null) { - final int[] ARGB = ramp.colors; - if (ARGB != null) { - final Color[] colors = new Color[ARGB.length]; - for (int i=0; i<colors.length; i++) { - colors[i] = new Color(ARGB[i], true); + final SimpleObjectProperty<ColorRamp> property = customizedColors.get(key(category)); + if (property != null) { + final ColorRamp ramp = property.getValue(); + if (ramp != null) { + final int[] ARGB = ramp.colors; + if (ARGB != null) { + final var colors = new Color[ARGB.length]; + for (int i=0; i<colors.length; i++) { + colors[i] = new Color(ARGB[i], true); + } + return colors; } - return colors; } } return null; @@ -157,15 +178,15 @@ final class CoverageStyling extends ColorColumnHandler<Category> implements Func */ @Override protected ColorRamp.Type applyColors(final Category category, final ColorRamp colors) { - final String key = key(category); - final ColorRamp old; + final SimpleObjectProperty<ColorRamp> property; if (colors != null) { - old = customizedColors.put(key, colors); + property = getObservableValue(category); + property.setValue(colors); } else { - old = customizedColors.remove(key); - } - if (canvas != null && !Objects.equals(colors, old)) { - canvas.stylingChanged(); + property = customizedColors.get(key(category)); + if (property != null) { + property.setValue(category.isQuantitative() ? ColorRamp.DEFAULT : null); + } } return category.isQuantitative() ? ColorRamp.Type.GRADIENT : ColorRamp.Type.SOLID; }
