diff --git a/src/main/java/com/sparrowwallet/sparrow/control/IntegerSpinner.java b/src/main/java/com/sparrowwallet/sparrow/control/IntegerSpinner.java new file mode 100644 index 00000000..fd165fb2 --- /dev/null +++ b/src/main/java/com/sparrowwallet/sparrow/control/IntegerSpinner.java @@ -0,0 +1,83 @@ +package com.sparrowwallet.sparrow.control; + +import javafx.beans.NamedArg; +import javafx.scene.control.Spinner; +import javafx.scene.control.SpinnerValueFactory; +import javafx.util.converter.IntegerStringConverter; + +public class IntegerSpinner extends Spinner { + public IntegerSpinner() { + super(); + setupEditor(); + } + + public IntegerSpinner(@NamedArg("min") int min, + @NamedArg("max") int max, + @NamedArg("initialValue") int initialValue) { + super(min, max, initialValue); + setupEditor(); + } + + public IntegerSpinner(@NamedArg("min") int min, + @NamedArg("max") int max, + @NamedArg("initialValue") int initialValue, + @NamedArg("amountToStepBy") int amountToStepBy) { + super(min, max, initialValue, amountToStepBy); + setupEditor(); + } + + private void setupEditor() { + getEditor().focusedProperty().addListener((observable, oldValue, newValue) -> { + if(newValue != null && !newValue) { + commitValue(); + } + }); + getEditor().textProperty().addListener((observable, oldValue, newValue) -> { + if(!newValue.matches("\\d*")) { + getEditor().setText(newValue.replaceAll("[^\\d]", "")); + } + }); + } + + public static class ValueFactory extends SpinnerValueFactory.IntegerSpinnerValueFactory { + public ValueFactory(@NamedArg("min") int min, + @NamedArg("max") int max) { + super(min, max); + setupConverter(min); + } + + public ValueFactory(@NamedArg("min") int min, + @NamedArg("max") int max, + @NamedArg("initialValue") int initialValue) { + super(min, max, initialValue); + setupConverter(initialValue); + } + + public ValueFactory(@NamedArg("min") int min, + @NamedArg("max") int max, + @NamedArg("initialValue") int initialValue, + @NamedArg("amountToStepBy") int amountToStepBy) { + super(min, max, initialValue, amountToStepBy); + setupConverter(initialValue); + } + + private void setupConverter(Integer defaultValue) { + setConverter(new IntegerStringConverter() { + @Override + public Integer fromString(String value) { + if(value == null) { + return null; + } + + value = value.trim(); + + if(value.length() < 1) { + return defaultValue; + } + + return Integer.valueOf(value); + } + }); + } + } +} diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java index b2479a75..3ddbc2cf 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java @@ -82,7 +82,7 @@ public class HeadersController extends TransactionFormController implements Init private TransactionDiagram transactionDiagram; @FXML - private Spinner version; + private IntegerSpinner version; @FXML private CopyableLabel segwit; @@ -112,10 +112,10 @@ public class HeadersController extends TransactionFormController implements Init private Field locktimeDateField; @FXML - private Spinner locktimeNone; + private IntegerSpinner locktimeNone; @FXML - private Spinner locktimeBlock; + private IntegerSpinner locktimeBlock; @FXML private Hyperlink locktimeCurrentHeight; @@ -243,8 +243,12 @@ public class HeadersController extends TransactionFormController implements Init updateTxId(); - version.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(1, 2, (int)tx.getVersion())); + version.setValueFactory(new IntegerSpinner.ValueFactory(1, 2, (int)tx.getVersion())); version.valueProperty().addListener((obs, oldValue, newValue) -> { + if(newValue == null || newValue < 1 || newValue > 2) { + return; + } + tx.setVersion(newValue); if(oldValue != null) { EventManager.get().post(new TransactionChangedEvent(tx)); @@ -305,9 +309,9 @@ public class HeadersController extends TransactionFormController implements Init futureDateWarning.managedProperty().bind(futureDateWarning.visibleProperty()); futureDateWarning.setVisible(false); - locktimeNone.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(0, (int)Transaction.MAX_BLOCK_LOCKTIME-1, 0)); + locktimeNone.setValueFactory(new IntegerSpinner.ValueFactory(0, (int)Transaction.MAX_BLOCK_LOCKTIME-1, 0)); if(tx.getLocktime() < Transaction.MAX_BLOCK_LOCKTIME) { - locktimeBlock.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(0, (int)Transaction.MAX_BLOCK_LOCKTIME-1, (int)tx.getLocktime())); + locktimeBlock.setValueFactory(new IntegerSpinner.ValueFactory(0, (int)Transaction.MAX_BLOCK_LOCKTIME-1, (int)tx.getLocktime())); if(tx.getLocktime() == 0) { locktimeToggleGroup.selectToggle(locktimeNoneType); } else { @@ -316,13 +320,17 @@ public class HeadersController extends TransactionFormController implements Init LocalDateTime date = Instant.now().atZone(ZoneId.systemDefault()).toLocalDateTime(); locktimeDate.setDateTimeValue(date); } else { - locktimeBlock.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(0, (int)Transaction.MAX_BLOCK_LOCKTIME-1)); + locktimeBlock.setValueFactory(new IntegerSpinner.ValueFactory(0, (int)Transaction.MAX_BLOCK_LOCKTIME-1)); LocalDateTime date = Instant.ofEpochSecond(tx.getLocktime()).atZone(ZoneId.systemDefault()).toLocalDateTime(); locktimeDate.setDateTimeValue(date); locktimeToggleGroup.selectToggle(locktimeDateType); } locktimeBlock.valueProperty().addListener((obs, oldValue, newValue) -> { + if(newValue == null || newValue < 0 || newValue >= Transaction.MAX_BLOCK_LOCKTIME) { + return; + } + tx.setLocktime(newValue); locktimeCurrentHeight.setVisible(headersForm.isEditable() && AppServices.getCurrentBlockHeight() != null && newValue < AppServices.getCurrentBlockHeight()); futureBlockWarning.setVisible(AppServices.getCurrentBlockHeight() != null && newValue > AppServices.getCurrentBlockHeight()); diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/InputController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/InputController.java index be69d705..ba599c3d 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/InputController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/InputController.java @@ -104,7 +104,7 @@ public class InputController extends TransactionFormController implements Initia private CopyableLabel locktimeAbsolute; @FXML - private Spinner locktimeRelativeBlocks; + private IntegerSpinner locktimeRelativeBlocks; @FXML private RelativeTimelockSpinner locktimeRelativeSeconds; @@ -406,7 +406,7 @@ public class InputController extends TransactionFormController implements Initia } }); - locktimeRelativeBlocks.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(0, (int)TransactionInput.RELATIVE_TIMELOCK_VALUE_MASK, 0)); + locktimeRelativeBlocks.setValueFactory(new IntegerSpinner.ValueFactory(0, (int)TransactionInput.RELATIVE_TIMELOCK_VALUE_MASK, 0)); locktimeRelativeBlocks.managedProperty().bind(locktimeRelativeBlocks.visibleProperty()); locktimeRelativeSeconds.managedProperty().bind(locktimeRelativeSeconds.visibleProperty()); locktimeRelativeCombo.getSelectionModel().selectedItemProperty().addListener((ov, old_toggle, new_toggle) -> { @@ -433,6 +433,10 @@ public class InputController extends TransactionFormController implements Initia } locktimeRelativeBlocks.valueProperty().addListener((obs, oldValue, newValue) -> { + if(newValue == null || newValue < 0 || newValue > TransactionInput.RELATIVE_TIMELOCK_VALUE_MASK) { + return; + } + setRelativeLocktime(txInput, transaction, oldValue != null); }); locktimeRelativeSeconds.valueProperty().addListener((obs, oldValue, newValue) -> { diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/AdvancedController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/AdvancedController.java index 4c94d754..e2150500 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/AdvancedController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/AdvancedController.java @@ -3,6 +3,7 @@ package com.sparrowwallet.sparrow.wallet; import com.sparrowwallet.drongo.wallet.Wallet; import com.sparrowwallet.sparrow.EventManager; import com.sparrowwallet.sparrow.control.DateStringConverter; +import com.sparrowwallet.sparrow.control.IntegerSpinner; import com.sparrowwallet.sparrow.event.SettingsChangedEvent; import javafx.collections.FXCollections; import javafx.collections.ObservableList; @@ -10,8 +11,6 @@ import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.ComboBox; import javafx.scene.control.DatePicker; -import javafx.scene.control.Spinner; -import javafx.scene.control.SpinnerValueFactory; import javafx.util.StringConverter; import java.net.URL; @@ -28,7 +27,7 @@ public class AdvancedController implements Initializable { private DatePicker birthDate; @FXML - private Spinner gapLimit; + private IntegerSpinner gapLimit; @FXML private ComboBox watchLast; @@ -50,8 +49,12 @@ public class AdvancedController implements Initializable { } }); - gapLimit.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(Wallet.DEFAULT_LOOKAHEAD, 9999, wallet.getGapLimit())); + gapLimit.setValueFactory(new IntegerSpinner.ValueFactory(Wallet.DEFAULT_LOOKAHEAD, 9999, wallet.getGapLimit())); gapLimit.valueProperty().addListener((observable, oldValue, newValue) -> { + if(newValue == null || newValue < Wallet.DEFAULT_LOOKAHEAD || newValue > 9999) { + return; + } + wallet.setGapLimit(newValue); if(!watchLast.getItems().equals(getWatchListItems(wallet))) { Integer value = watchLast.getValue(); diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/MixToController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/MixToController.java index de75cc4b..7832bf2a 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/MixToController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/MixToController.java @@ -7,6 +7,7 @@ import com.sparrowwallet.drongo.wallet.StandardAccount; import com.sparrowwallet.drongo.wallet.Wallet; import com.sparrowwallet.sparrow.AppServices; import com.sparrowwallet.sparrow.EventManager; +import com.sparrowwallet.sparrow.control.IntegerSpinner; import com.sparrowwallet.sparrow.event.MixToConfigChangedEvent; import com.sparrowwallet.sparrow.whirlpool.Whirlpool; import javafx.collections.FXCollections; @@ -31,7 +32,7 @@ public class MixToController implements Initializable { private ComboBox mixToWallets; @FXML - private Spinner minMixes; + private IntegerSpinner minMixes; @FXML private ComboBox indexRange; @@ -94,8 +95,12 @@ public class MixToController implements Initializable { }); int initialMinMixes = mixConfig.getMinMixes() == null ? Whirlpool.DEFAULT_MIXTO_MIN_MIXES : mixConfig.getMinMixes(); - minMixes.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(1, 10000, initialMinMixes)); + minMixes.setValueFactory(new IntegerSpinner.ValueFactory(1, 10000, initialMinMixes)); minMixes.valueProperty().addListener((observable, oldValue, newValue) -> { + if(newValue == null || newValue < 1 || newValue > 10000) { + return; + } + mixConfig.setMinMixes(newValue); EventManager.get().post(new MixToConfigChangedEvent(wallet)); }); diff --git a/src/main/resources/com/sparrowwallet/sparrow/transaction/headers.fxml b/src/main/resources/com/sparrowwallet/sparrow/transaction/headers.fxml index e70101fc..1dc7c5e7 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/transaction/headers.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/transaction/headers.fxml @@ -28,6 +28,7 @@ + @@ -71,7 +72,7 @@
- + @@ -94,10 +95,10 @@ - + - + - + diff --git a/src/main/resources/com/sparrowwallet/sparrow/wallet/advanced.fxml b/src/main/resources/com/sparrowwallet/sparrow/wallet/advanced.fxml index 7852805c..31cbc09e 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/wallet/advanced.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/wallet/advanced.fxml @@ -10,6 +10,7 @@ +
@@ -31,7 +32,7 @@ - + diff --git a/src/main/resources/com/sparrowwallet/sparrow/wallet/mixto.fxml b/src/main/resources/com/sparrowwallet/sparrow/wallet/mixto.fxml index 8a3ec707..86488c49 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/wallet/mixto.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/wallet/mixto.fxml @@ -11,8 +11,8 @@ - +
@@ -34,7 +34,7 @@ - +