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); } } 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; diff --git a/src/nl/jeroenhoek/josm/gridify/ui/PositiveSpinner.java b/src/nl/jeroenhoek/josm/gridify/ui/PositiveSpinner.java index 5e2b56c..e530878 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,27 +84,30 @@ 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)); } } @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); }