From 60ea5a4095df04381be512d4163f2e1ce5028fa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Tim=C3=A1r?= <23311361+gabortim@users.noreply.github.com> Date: Tue, 25 Aug 2026 11:43:36 +0200 Subject: [PATCH 1/4] Use Optional.ifPresent() in GridifySettingsDialog --- .../jeroenhoek/josm/gridify/ui/GridifySettingsDialog.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/nl/jeroenhoek/josm/gridify/ui/GridifySettingsDialog.java b/src/nl/jeroenhoek/josm/gridify/ui/GridifySettingsDialog.java index 10afd5a..f653003 100644 --- a/src/nl/jeroenhoek/josm/gridify/ui/GridifySettingsDialog.java +++ b/src/nl/jeroenhoek/josm/gridify/ui/GridifySettingsDialog.java @@ -83,7 +83,7 @@ public GridifySettingsDialog(InputData inputData, GridifySettings settings) { constraints.insets = insetsIndent; controlPanel.add(gridSizePanel, constraints); - if (inputData.getSourceWay().isPresent()) { + inputData.getSourceWay().ifPresent(sourceWay -> { JLabel wayLabel = new JLabel(tr("Source way")); wayLabel.setBorder(underline); constraints.gridy = 4; @@ -92,18 +92,18 @@ public GridifySettingsDialog(InputData inputData, GridifySettings settings) { // Always check the 'delete source way' option when a new way is used as template. // It tends to have been drawn specifically to cut up. - boolean deleteSourceWay = inputData.getSourceWay().get().isNew(); + boolean deleteSourceWay = sourceWay.isNew(); sourceWayPanel = new SourceWayPanel( settings.copyTagsFromSource(), deleteSourceWay || settings.deleteSource(), - !inputData.getSourceWay().get().getReferrers().isEmpty(), + !sourceWay.getReferrers().isEmpty(), this::fireChangeEvent ); constraints.gridy = 5; constraints.insets = insetsIndent; controlPanel.add(sourceWayPanel, constraints); - } + }); JLabel statsLabel = new JLabel(tr("Statistics")); constraints.gridy = 6; From 9f010f3b32c6bb8aa0b617217d626b0c21498d1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Tim=C3=A1r?= <23311361+gabortim@users.noreply.github.com> Date: Tue, 25 Aug 2026 11:45:50 +0200 Subject: [PATCH 2/4] Use spinner constants in bound checks --- .../josm/gridify/ui/GridSizePanel.java | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/nl/jeroenhoek/josm/gridify/ui/GridSizePanel.java b/src/nl/jeroenhoek/josm/gridify/ui/GridSizePanel.java index 9fe81d0..da0e856 100644 --- a/src/nl/jeroenhoek/josm/gridify/ui/GridSizePanel.java +++ b/src/nl/jeroenhoek/josm/gridify/ui/GridSizePanel.java @@ -59,34 +59,36 @@ void flipRowsColumns() { } void setRowCount(int rows) { - if (rows < 1 || rows > 1000) return; + if (rows < PositiveSpinner.SPINNER_MIN_VALUE || rows > PositiveSpinner.SPINNER_MAX_VALUE) return; this.rows = rows; this.spinnerRows.setValue(rows); changeCallback.changed(getRowCount(), getColumnCount()); } void setColumnCount(int columns) { - if (columns < 1 || columns > 1000) return; + if (columns < PositiveSpinner.SPINNER_MIN_VALUE || columns > PositiveSpinner.SPINNER_MAX_VALUE) return; this.columns = columns; this.spinnerColumns.setValue(columns); changeCallback.changed(getRowCount(), getColumnCount()); } void nudgeRowCount(Nudge direction) { - if (direction == Nudge.INCREMENT || this.rows > 1) { - this.rows += direction == Nudge.INCREMENT ? 1 : -1; - this.spinnerRows.setValue(rows); + int newRows = this.rows + (direction == Nudge.INCREMENT ? 1 : -1); + if (newRows >= PositiveSpinner.SPINNER_MIN_VALUE && newRows <= PositiveSpinner.SPINNER_MAX_VALUE) { + this.rows = newRows; + this.spinnerRows.setValue(newRows); this.spinnerRows.caretToEnd(); - changeCallback.changed(getRowCount(), getColumnCount()); + changeCallback.changed(this.rows, this.columns); } } void nudgeColumnCount(Nudge direction) { - if (direction == Nudge.INCREMENT || this.columns > 1) { - this.columns += direction == Nudge.INCREMENT ? 1 : -1; - this.spinnerColumns.setValue(columns); + int newCols = this.columns + (direction == Nudge.INCREMENT ? 1 : -1); + if (newCols >= PositiveSpinner.SPINNER_MIN_VALUE && newCols <= PositiveSpinner.SPINNER_MAX_VALUE) { + this.columns = newCols; + this.spinnerColumns.setValue(newCols); this.spinnerColumns.caretToEnd(); - changeCallback.changed(getRowCount(), getColumnCount()); + changeCallback.changed(this.rows, this.columns); } } From 6bc58dd9d50e1a33465a3459836d591163bcd1cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Tim=C3=A1r?= <23311361+gabortim@users.noreply.github.com> Date: Tue, 25 Aug 2026 12:02:10 +0200 Subject: [PATCH 3/4] Simplify mouse wheel tick calculation logic --- .../josm/gridify/ui/PositiveSpinner.java | 42 +++++++++---------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/src/nl/jeroenhoek/josm/gridify/ui/PositiveSpinner.java b/src/nl/jeroenhoek/josm/gridify/ui/PositiveSpinner.java index 5e2b56c..f44f3b9 100644 --- a/src/nl/jeroenhoek/josm/gridify/ui/PositiveSpinner.java +++ b/src/nl/jeroenhoek/josm/gridify/ui/PositiveSpinner.java @@ -11,6 +11,7 @@ import java.awt.Dimension; import java.awt.Font; import java.awt.event.FocusEvent; +import java.text.ParseException; import java.util.Objects; /** @@ -42,24 +43,19 @@ public PositiveSpinner(int defaultValue, ValueChanged changeCallback) { // Kind of weird that the default JSpinner doesn't do this. addMouseWheelListener(e -> { - int ticks = e.getWheelRotation(); - Object newValue = null; - if (ticks > 0) { - for (int tick = 0; tick < ticks; tick++) { - Object previous = getPreviousValue(); - if (previous == null) break; - newValue = previous; - } - } else if (ticks < 0) { - for (int tick = 0; tick > ticks; tick--) { - Object next = getNextValue(); - if (next == null) break; - newValue = next; - } + try { + commitEdit(); + } catch (ParseException ignore) { } + int ticks = e.getWheelRotation(); + int current = (Integer) getValue(); + + // e.getWheelRotation() is positive when scrolling down (decrease) and negative when scrolling up (increase) + int newValue = Math.max(SPINNER_MIN_VALUE, Math.min(SPINNER_MAX_VALUE, current - ticks)); - if (newValue != null) { + if (newValue != current) { setValue(newValue); + caretToEnd(); } }); @@ -88,19 +84,21 @@ public void changedUpdate(DocumentEvent e) { } void callbackIfChanged() { - Integer newValue; + String text = field.getText(); + if (text.isBlank()) { + return; + } + + int newValue; try { - newValue = Integer.parseInt(field.getText()); + newValue = Integer.parseInt(text); } catch (NumberFormatException e) { - // Ignore. return; } if (!Objects.equals(newValue, lastValue)) { - SwingUtilities.invokeLater(() -> { - this.lastValue = newValue; - changeCallback.onChange(newValue); - }); + this.lastValue = newValue; + SwingUtilities.invokeLater(() -> changeCallback.onChange(newValue)); } } From 54c975123153338c4c253521769b0b148e776ee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Tim=C3=A1r?= <23311361+gabortim@users.noreply.github.com> Date: Tue, 25 Aug 2026 12:02:24 +0200 Subject: [PATCH 4/4] Fix JOSM/gridify/issues/23 --- src/nl/jeroenhoek/josm/gridify/ui/PositiveSpinner.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/nl/jeroenhoek/josm/gridify/ui/PositiveSpinner.java b/src/nl/jeroenhoek/josm/gridify/ui/PositiveSpinner.java index f44f3b9..e530878 100644 --- a/src/nl/jeroenhoek/josm/gridify/ui/PositiveSpinner.java +++ b/src/nl/jeroenhoek/josm/gridify/ui/PositiveSpinner.java @@ -104,9 +104,10 @@ void callbackIfChanged() { @Override public void setValue(Object value) { - // No need to update the value if nothing changes. This prevents the caret being placed at an awkward position. - if (Objects.equals(value, lastValue)) return; + // Check against the actual model value instead of lastValue so the model doesn't get stuck. + if (Objects.equals(value, getValue())) return; + this.lastValue = (Integer) value; super.setValue(value); }