* Optional ViewBuilder: * - Replacement for FXML view definitions. - * + *
* Note: Don't assign the root node as it is defined in the base class!
- *
*/
public class CreateOfferCodeBehind extends CachedViewController {
private static final Logger log = LoggerFactory.getLogger(CreateOfferCodeBehind.class);
@@ -154,15 +157,25 @@ public class CreateOfferCodeBehind extends CachedViewController {
///////////////////////////////////////////////////////////////////////////////////////////
private void setupListeners() {
- volumeTextField.focusedProperty().addListener((observableValue, oldValue,
- newValue) -> presenter.validateVolumeOnFocusOut(oldValue,
- newValue, volumeTextField.getText()));
- amountTextField.focusedProperty().addListener((observableValue, oldValue,
- newValue) -> presenter.onFocusOutAmountTextField(oldValue,
- newValue));
- priceTextField.focusedProperty().addListener((observableValue, oldValue,
- newValue) -> presenter.onFocusOutPriceTextField(oldValue,
- newValue));
+ volumeTextField.focusedProperty().addListener((o, oldValue, newValue) -> {
+ presenter.onFocusOutVolumeTextField(oldValue, newValue, volumeTextField.getText());
+ volumeTextField.setText(presenter.volume.get());
+ });
+
+ amountTextField.focusedProperty().addListener((o, oldValue, newValue) -> {
+ presenter.onFocusOutAmountTextField(oldValue, newValue);
+ amountTextField.setText(presenter.amount.get());
+ });
+
+ priceTextField.focusedProperty().addListener((o, oldValue, newValue) -> {
+ presenter.onFocusOutPriceTextField(oldValue, newValue);
+ priceTextField.setText(presenter.price.get());
+ });
+
+ minAmountTextField.focusedProperty().addListener((o, oldValue, newValue) -> {
+ presenter.onFocusOutMinAmountTextField(oldValue, newValue);
+ minAmountTextField.setText(presenter.minAmount.get());
+ });
presenter.needsInputValidation.addListener((o, oldValue, newValue) -> {
if (newValue) {
@@ -173,17 +186,36 @@ public class CreateOfferCodeBehind extends CachedViewController {
}
});
- presenter.showVolumeAdjustedWarning.addListener((o, oldValue, newValue) -> {
+ presenter.showWarningInvalidBtcDecimalPlaces.addListener((o, oldValue, newValue) -> {
+ if (newValue) {
+ Popups.openWarningPopup("Warning", "The amount you have entered exceeds the number of allowed decimal" +
+ " places.\nThe amount has been adjusted to 4 decimal places.");
+ presenter.showWarningInvalidBtcDecimalPlaces.set(false);
+ }
+ });
+
+ presenter.showWarningInvalidFiatDecimalPlaces.addListener((o, oldValue, newValue) -> {
+ if (newValue) {
+ Popups.openWarningPopup("Warning", "The amount you have entered exceeds the number of allowed decimal" +
+ " places.\nThe amount has been adjusted to 2 decimal places.");
+ presenter.showWarningInvalidFiatDecimalPlaces.set(false);
+ }
+ });
+
+ presenter.showWarningInvalidBtcFractions.addListener((o, oldValue, newValue) -> {
if (newValue) {
Popups.openWarningPopup("Warning", "The total volume you have entered leads to invalid fractional " +
"Bitcoin amounts.\nThe amount has been adjusted and a new total volume be calculated from it.");
+ presenter.showWarningInvalidBtcFractions.set(false);
volumeTextField.setText(presenter.volume.get());
}
});
+
presenter.requestPlaceOfferFailed.addListener((o, oldValue, newValue) -> {
if (newValue) {
Popups.openErrorPopup("Error", "An error occurred when placing the offer.\n" +
presenter.requestPlaceOfferErrorMessage);
+ presenter.requestPlaceOfferFailed.set(false);
}
});
}
@@ -231,26 +263,27 @@ public class CreateOfferCodeBehind extends CachedViewController {
}
private void setupTextFieldValidators() {
- /* BtcValidator amountValidator = new BtcValidator();
- amountTextField.setNumberValidator(amountValidator);
- amountTextField.setErrorPopupLayoutReference((Region) amountTextField.getParent());
+ Region referenceNode = (Region) amountTextField.getParent();
+
+ BtcValidator amountValidator = new BtcValidator();
+ amountTextField.setValidator(amountValidator);
+ amountTextField.setErrorPopupLayoutReference(referenceNode);
- priceTextField.setNumberValidator(new FiatValidator());
- priceTextField.setErrorPopupLayoutReference((Region) amountTextField.getParent());
+ priceTextField.setValidator(new FiatValidator());
+ priceTextField.setErrorPopupLayoutReference(referenceNode);
- BtcValidator volumeValidator = new BtcValidator();
- volumeTextField.setNumberValidator(volumeValidator);
- volumeTextField.setErrorPopupLayoutReference((Region) volumeTextField.getParent());
+ volumeTextField.setValidator(new FiatValidator());
+ volumeTextField.setErrorPopupLayoutReference(referenceNode);
BtcValidator minAmountValidator = new BtcValidator();
- minAmountTextField.setNumberValidator(minAmountValidator);
+ minAmountTextField.setValidator(minAmountValidator);
ValidationHelper.setupMinAmountInRangeOfAmountValidation(amountTextField,
- minAmountTextField,
- presenter.amount,
- presenter.minAmount,
- amountValidator,
- minAmountValidator);*/
+ minAmountTextField,
+ presenter.amount,
+ presenter.minAmount,
+ amountValidator,
+ minAmountValidator);
}
}
diff --git a/src/main/java/io/bitsquare/gui/trade/createoffer/CreateOfferModel.java b/src/main/java/io/bitsquare/gui/trade/createoffer/CreateOfferModel.java
index 9b110ed50d..77e154cc4c 100644
--- a/src/main/java/io/bitsquare/gui/trade/createoffer/CreateOfferModel.java
+++ b/src/main/java/io/bitsquare/gui/trade/createoffer/CreateOfferModel.java
@@ -75,7 +75,7 @@ class CreateOfferModel {
Coin minAmountAsCoin;
Coin collateralAsCoin;
Fiat priceAsFiat;
- Fiat tradeVolumeAsFiat;
+ Fiat volumeAsFiat;
AddressEntry addressEntry;
final StringProperty requestPlaceOfferErrorMessage = new SimpleStringProperty();
diff --git a/src/main/java/io/bitsquare/gui/trade/createoffer/CreateOfferPresenter.java b/src/main/java/io/bitsquare/gui/trade/createoffer/CreateOfferPresenter.java
index 260d1dfd96..3669024301 100644
--- a/src/main/java/io/bitsquare/gui/trade/createoffer/CreateOfferPresenter.java
+++ b/src/main/java/io/bitsquare/gui/trade/createoffer/CreateOfferPresenter.java
@@ -81,7 +81,9 @@ class CreateOfferPresenter {
final BooleanProperty isPlaceOfferButtonVisible = new SimpleBooleanProperty(true);
final BooleanProperty isPlaceOfferButtonDisabled = new SimpleBooleanProperty();
final BooleanProperty needsInputValidation = new SimpleBooleanProperty();
- final BooleanProperty showVolumeAdjustedWarning = new SimpleBooleanProperty();
+ final BooleanProperty showWarningInvalidBtcFractions = new SimpleBooleanProperty();
+ final BooleanProperty showWarningInvalidFiatDecimalPlaces = new SimpleBooleanProperty();
+ final BooleanProperty showWarningInvalidBtcDecimalPlaces = new SimpleBooleanProperty();
final BooleanProperty showTransactionPublishedScreen = new SimpleBooleanProperty();
final BooleanProperty requestPlaceOfferFailed = new SimpleBooleanProperty();
@@ -161,7 +163,7 @@ class CreateOfferPresenter {
model.minAmountAsCoin = orderBookFilter.getAmount();
// TODO use Fiat in orderBookFilter
- model.priceAsFiat = parseToFiat(String.valueOf(orderBookFilter.getPrice()));
+ model.priceAsFiat = parseToFiatWith2Decimals(String.valueOf(orderBookFilter.getPrice()));
directionLabel.set(model.getDirection() == Direction.BUY ? "Buy:" : "Sell:");
amount.set(formatBtc(model.amountAsCoin));
@@ -175,10 +177,10 @@ class CreateOfferPresenter {
///////////////////////////////////////////////////////////////////////////////////////////
void placeOffer() {
- model.amountAsCoin = parseToCoin(amount.get());
- model.minAmountAsCoin = parseToCoin(minAmount.get());
- model.priceAsFiat = parseToFiat(price.get());
- model.minAmountAsCoin = parseToCoin(minAmount.get());
+ model.amountAsCoin = parseToBtcWith4Decimals(amount.get());
+ model.minAmountAsCoin = parseToBtcWith4Decimals(minAmount.get());
+ model.priceAsFiat = parseToFiatWith2Decimals(price.get());
+ model.minAmountAsCoin = parseToBtcWith4Decimals(minAmount.get());
needsInputValidation.set(true);
@@ -200,53 +202,64 @@ class CreateOfferPresenter {
// bindBidirectional for amount, price, volume and minAmount
amount.addListener(ov -> {
- model.amountAsCoin = parseToCoin(amount.get());
+ model.amountAsCoin = parseToBtcWith4Decimals(amount.get());
calculateVolume();
calculateTotalToPay();
calculateCollateral();
});
price.addListener(ov -> {
- model.priceAsFiat = parseToFiat(price.get());
+ model.priceAsFiat = parseToFiatWith2Decimals(price.get());
calculateVolume();
calculateTotalToPay();
calculateCollateral();
});
volume.addListener(ov -> {
- model.tradeVolumeAsFiat = parseToFiat(volume.get());
+ model.volumeAsFiat = parseToFiatWith2Decimals(volume.get());
calculateAmount();
calculateTotalToPay();
calculateCollateral();
});
}
+ void onFocusOutAmountTextField(Boolean oldValue, Boolean newValue) {
- // We adjust the volume if fractional coins result from volume/price division on focus out
- void validateVolumeOnFocusOut(Boolean oldValue, Boolean newValue, String volumeTextFieldText) {
if (oldValue && !newValue) {
+ showWarningInvalidBtcDecimalPlaces.set(!hasBtcValidDecimals(amount.get()));
+ model.amountAsCoin = parseToBtcWith4Decimals(amount.get());
+ amount.set(formatBtc(model.amountAsCoin));
calculateVolume();
- if (!formatFiat(parseToFiat(volumeTextFieldText)).equals(volume.get()))
- showVolumeAdjustedWarning.set(true);
}
-
-
- //
- // only on focus out and ignore focus loss from window
- /* if (!newValue && volumeTextField.getScene() != null && volumeTextField.getScene().getWindow().isFocused())
- amountTextField.reValidate();*/
}
- void onFocusOutAmountTextField(Boolean oldValue, Boolean newValue) {
- // only on focus out and ignore focus loss from window
- /* if (!newValue && amountTextField.getScene() != null && amountTextField.getScene().getWindow().isFocused())
- volumeTextField.reValidate();*/
+ void onFocusOutMinAmountTextField(Boolean oldValue, Boolean newValue) {
+
+ if (oldValue && !newValue) {
+ showWarningInvalidBtcDecimalPlaces.set(!hasBtcValidDecimals(minAmount.get()));
+ model.minAmountAsCoin = parseToBtcWith4Decimals(minAmount.get());
+ minAmount.set(formatBtc(model.minAmountAsCoin));
+ }
+ }
+
+ void onFocusOutVolumeTextField(Boolean oldValue, Boolean newValue, String volumeTextFieldText) {
+ if (oldValue && !newValue) {
+ showWarningInvalidFiatDecimalPlaces.set(!hasFiatValidDecimals(volume.get()));
+ model.volumeAsFiat = parseToFiatWith2Decimals(volume.get());
+ volume.set(formatFiat(model.volumeAsFiat));
+ calculateAmount();
+
+ showWarningInvalidBtcFractions.set(!formatFiat(parseToFiatWith2Decimals(volumeTextFieldText)).equals
+ (volume.get()));
+ }
}
void onFocusOutPriceTextField(Boolean oldValue, Boolean newValue) {
- // only on focus out and ignore focus loss from window
- /* if (!newValue && priceTextField.getScene() != null && priceTextField.getScene().getWindow().isFocused())
- volumeTextField.reValidate();*/
+ if (oldValue && !newValue) {
+ showWarningInvalidFiatDecimalPlaces.set(!hasFiatValidDecimals(price.get()));
+ model.priceAsFiat = parseToFiatWith2Decimals(price.get());
+ price.set(formatFiat(model.priceAsFiat));
+ }
}
@@ -269,24 +282,24 @@ class CreateOfferPresenter {
}
private void calculateVolume() {
- model.amountAsCoin = parseToCoin(amount.get());
- model.priceAsFiat = parseToFiat(price.get());
+ model.amountAsCoin = parseToBtcWith4Decimals(amount.get());
+ model.priceAsFiat = parseToFiatWith2Decimals(price.get());
if (model.priceAsFiat != null && model.amountAsCoin != null && !model.amountAsCoin.isZero()) {
- model.tradeVolumeAsFiat = new ExchangeRate(model.priceAsFiat).coinToFiat(model.amountAsCoin);
- volume.set(formatFiat(model.tradeVolumeAsFiat));
+ model.volumeAsFiat = new ExchangeRate(model.priceAsFiat).coinToFiat(model.amountAsCoin);
+ volume.set(formatFiat(model.volumeAsFiat));
}
}
private void calculateAmount() {
- model.tradeVolumeAsFiat = parseToFiat(volume.get());
- model.priceAsFiat = parseToFiat(price.get());
+ model.volumeAsFiat = parseToFiatWith2Decimals(volume.get());
+ model.priceAsFiat = parseToFiatWith2Decimals(price.get());
- if (model.tradeVolumeAsFiat != null && model.priceAsFiat != null && !model.priceAsFiat.isZero()) {
- model.amountAsCoin = new ExchangeRate(model.priceAsFiat).fiatToCoin(model.tradeVolumeAsFiat);
+ if (model.volumeAsFiat != null && model.priceAsFiat != null && !model.priceAsFiat.isZero()) {
+ model.amountAsCoin = new ExchangeRate(model.priceAsFiat).fiatToCoin(model.volumeAsFiat);
// If we got a btc value with more then 4 decimals we convert it to max 4 decimals
- model.amountAsCoin = applyFormatRules(model.amountAsCoin);
+ model.amountAsCoin = reduceto4Dezimals(model.amountAsCoin);
amount.set(formatBtc(model.amountAsCoin));
calculateTotalToPay();
calculateCollateral();
diff --git a/src/main/java/io/bitsquare/gui/trade/createoffer/CreateOfferView.fxml b/src/main/java/io/bitsquare/gui/trade/createoffer/CreateOfferView.fxml
index fd363ac20a..5a54cdb44d 100644
--- a/src/main/java/io/bitsquare/gui/trade/createoffer/CreateOfferView.fxml
+++ b/src/main/java/io/bitsquare/gui/trade/createoffer/CreateOfferView.fxml
@@ -48,11 +48,11 @@