diff --git a/desktop/src/main/java/bisq/desktop/components/SearchComboBox.java b/desktop/src/main/java/bisq/desktop/components/SearchComboBox.java index 0038635dacb..6a02c2ee3dd 100644 --- a/desktop/src/main/java/bisq/desktop/components/SearchComboBox.java +++ b/desktop/src/main/java/bisq/desktop/components/SearchComboBox.java @@ -19,22 +19,23 @@ import bisq.common.UserThread; -import javafx.scene.control.ComboBox; +import com.jfoenix.controls.JFXComboBox; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.collections.transformation.FilteredList; -public class SearchComboBox extends ComboBox { +public class SearchComboBox extends JFXComboBox { @SuppressWarnings("CanBeFinal") private FilteredList filteredList; public SearchComboBox() { - this(FXCollections.observableArrayList()); + this(FXCollections.observableArrayList()); } - public SearchComboBox(final ObservableList items) { + private SearchComboBox(final ObservableList items) { super(new FilteredList<>(items)); + filteredList = new FilteredList<>(items); setEditable(true); @@ -43,8 +44,7 @@ public SearchComboBox(final ObservableList items) { setItems(filteredList); }); getEditor().textProperty().addListener((observable, oldValue, newValue) -> { - if (!filteredList.stream().filter(item -> getConverter().toString(item).equals(newValue)). - findAny().isPresent()) { + if (filteredList.stream().noneMatch(item -> getConverter().toString(item).equals(newValue))) { UserThread.execute(() -> { filteredList.setPredicate(item -> newValue.isEmpty() || getConverter().toString(item).toLowerCase().contains(newValue.toLowerCase())); diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/CryptoCurrencyForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/CryptoCurrencyForm.java index 8fd9a23b5c0..86d0005a36a 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/CryptoCurrencyForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/CryptoCurrencyForm.java @@ -38,7 +38,6 @@ import org.apache.commons.lang3.StringUtils; -import javafx.scene.control.ComboBox; import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; @@ -52,6 +51,7 @@ import static bisq.desktop.util.FormBuilder.addTopLabelTextField; import static bisq.desktop.util.FormBuilder.addTopLabelTextFieldWithCopyIcon; +import static bisq.desktop.util.GUIUtil.getComboBoxButtonCell; public class CryptoCurrencyForm extends PaymentMethodForm { private final CryptoCurrencyAccount cryptoCurrencyAccount; @@ -60,8 +60,6 @@ public class CryptoCurrencyForm extends PaymentMethodForm { private InputTextField addressInputTextField; - private ComboBox currencyComboBox; - public static int addFormForBuyer(GridPane gridPane, int gridRow, PaymentAccountPayload paymentAccountPayload, @@ -158,6 +156,12 @@ protected void addTradeCurrencyComboBox() { currencyComboBox = FormBuilder.addLabelSearchComboBox(gridPane, ++gridRow, Res.get("payment.altcoin"), Layout.FIRST_ROW_AND_GROUP_DISTANCE).second; currencyComboBox.setPromptText(Res.get("payment.select.altcoin")); + currencyComboBox.setButtonCell(getComboBoxButtonCell(Res.get("payment.select.altcoin"), currencyComboBox)); + + currencyComboBox.getEditor().focusedProperty().addListener(observable -> { + currencyComboBox.setPromptText(""); + }); + currencyComboBox.setItems(FXCollections.observableArrayList(CurrencyUtil.getWhiteListedSortedCryptoCurrencies(assetService))); currencyComboBox.setVisibleRowCount(Math.min(currencyComboBox.getItems().size(), 15)); currencyComboBox.setConverter(new StringConverter() { @@ -175,6 +179,10 @@ public TradeCurrency fromString(String s) { } }); currencyComboBox.setOnAction(e -> { + + addressInputTextField.resetValidation(); + addressInputTextField.validate(); + paymentAccount.setSingleTradeCurrency(currencyComboBox.getSelectionModel().getSelectedItem()); updateFromInputs(); }); diff --git a/desktop/src/main/java/bisq/desktop/components/paymentmethods/PaymentMethodForm.java b/desktop/src/main/java/bisq/desktop/components/paymentmethods/PaymentMethodForm.java index f465a39892c..2bb34ffd673 100644 --- a/desktop/src/main/java/bisq/desktop/components/paymentmethods/PaymentMethodForm.java +++ b/desktop/src/main/java/bisq/desktop/components/paymentmethods/PaymentMethodForm.java @@ -309,7 +309,7 @@ public int getGridRow() { } public int getRowSpan() { - return gridRow - gridRowFrom + 1; + return gridRow - gridRowFrom + 2; } public PaymentAccount getPaymentAccount() { diff --git a/desktop/src/main/java/bisq/desktop/main/account/content/PaymentAccountsView.java b/desktop/src/main/java/bisq/desktop/main/account/content/PaymentAccountsView.java new file mode 100644 index 00000000000..d4a051dd9fc --- /dev/null +++ b/desktop/src/main/java/bisq/desktop/main/account/content/PaymentAccountsView.java @@ -0,0 +1,133 @@ +package bisq.desktop.main.account.content; + +import bisq.desktop.common.model.ActivatableWithDataModel; +import bisq.desktop.common.view.ActivatableViewAndModel; +import bisq.desktop.components.AutoTooltipButton; +import bisq.desktop.components.AutoTooltipLabel; +import bisq.desktop.main.overlays.popups.Popup; +import bisq.desktop.util.ImageUtil; + +import bisq.core.locale.Res; +import bisq.core.payment.PaymentAccount; + +import bisq.common.UserThread; + +import javafx.scene.Node; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; +import javafx.scene.image.ImageView; +import javafx.scene.layout.AnchorPane; + +import javafx.beans.value.ChangeListener; + +import javafx.collections.ObservableList; + +import javafx.util.Callback; + +import java.util.concurrent.TimeUnit; + +public abstract class PaymentAccountsView extends ActivatableViewAndModel { + + protected ListView paymentAccountsListView; + protected ChangeListener paymentAccountChangeListener; + protected Button addAccountButton, exportButton, importButton; + + public PaymentAccountsView(M model) { + super(model); + } + + @Override + public void initialize() { + buildForm(); + paymentAccountChangeListener = (observable, oldValue, newValue) -> { + if (newValue != null) + onSelectAccount(newValue); + }; + Label placeholder = new AutoTooltipLabel(Res.get("shared.noAccountsSetupYet")); + placeholder.setWrapText(true); + paymentAccountsListView.setPlaceholder(placeholder); + } + + @Override + protected void activate() { + paymentAccountsListView.setItems(getPaymentAccounts()); + paymentAccountsListView.getSelectionModel().selectedItemProperty().addListener(paymentAccountChangeListener); + addAccountButton.setOnAction(event -> addNewAccount()); + exportButton.setOnAction(event -> exportAccounts()); + importButton.setOnAction(event -> importAccounts()); + } + + @Override + protected void deactivate() { + paymentAccountsListView.getSelectionModel().selectedItemProperty().removeListener(paymentAccountChangeListener); + addAccountButton.setOnAction(null); + exportButton.setOnAction(null); + importButton.setOnAction(null); + } + + protected void onDeleteAccount(PaymentAccount paymentAccount) { + new Popup<>().warning(Res.get("shared.askConfirmDeleteAccount")) + .actionButtonText(Res.get("shared.yes")) + .onAction(() -> { + boolean isPaymentAccountUsed = deleteAccountFromModel(paymentAccount); + if (!isPaymentAccountUsed) + removeSelectAccountForm(); + else + UserThread.runAfter(() -> new Popup<>().warning( + Res.get("shared.cannotDeleteAccount")) + .show(), 100, TimeUnit.MILLISECONDS); + }) + .closeButtonText(Res.get("shared.cancel")) + .show(); + } + + protected void setPaymentAccountsCellFactory() { + paymentAccountsListView.setCellFactory(new Callback, ListCell>() { + @Override + public ListCell call(ListView list) { + return new ListCell() { + final Label label = new AutoTooltipLabel(); + final ImageView icon = ImageUtil.getImageViewById(ImageUtil.REMOVE_ICON); + final Button removeButton = new AutoTooltipButton("", icon); + final AnchorPane pane = new AnchorPane(label, removeButton); + + { + label.setLayoutY(5); + removeButton.setId("icon-button"); + AnchorPane.setRightAnchor(removeButton, 0d); + } + + @Override + public void updateItem(final PaymentAccount item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) { + label.setText(item.getAccountName()); + removeButton.setOnAction(e -> onDeleteAccount(item)); + setGraphic(pane); + } else { + setGraphic(null); + } + } + }; + } + }); + } + + protected abstract void removeSelectAccountForm(); + + protected abstract boolean deleteAccountFromModel(PaymentAccount paymentAccount); + + protected abstract void importAccounts(); + + protected abstract void exportAccounts(); + + protected abstract void addNewAccount(); + + protected abstract ObservableList getPaymentAccounts(); + + protected abstract void buildForm(); + + protected abstract void onSelectAccount(PaymentAccount paymentAccount); +} diff --git a/desktop/src/main/java/bisq/desktop/main/account/content/altcoinaccounts/AltCoinAccountsView.java b/desktop/src/main/java/bisq/desktop/main/account/content/altcoinaccounts/AltCoinAccountsView.java index 2958585f34e..6c34755ff02 100644 --- a/desktop/src/main/java/bisq/desktop/main/account/content/altcoinaccounts/AltCoinAccountsView.java +++ b/desktop/src/main/java/bisq/desktop/main/account/content/altcoinaccounts/AltCoinAccountsView.java @@ -17,16 +17,13 @@ package bisq.desktop.main.account.content.altcoinaccounts; -import bisq.desktop.common.view.ActivatableViewAndModel; import bisq.desktop.common.view.FxmlView; -import bisq.desktop.components.AutoTooltipButton; -import bisq.desktop.components.AutoTooltipLabel; import bisq.desktop.components.TitledGroupBg; import bisq.desktop.components.paymentmethods.CryptoCurrencyForm; import bisq.desktop.components.paymentmethods.PaymentMethodForm; +import bisq.desktop.main.account.content.PaymentAccountsView; import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.util.FormBuilder; -import bisq.desktop.util.ImageUtil; import bisq.desktop.util.Layout; import bisq.core.dao.governance.asset.AssetService; @@ -41,7 +38,6 @@ import bisq.core.util.BSFormatter; import bisq.core.util.validation.InputValidator; -import bisq.common.UserThread; import bisq.common.util.Tuple2; import bisq.common.util.Tuple3; @@ -51,18 +47,11 @@ import javafx.scene.control.Button; import javafx.scene.control.Label; -import javafx.scene.control.ListCell; import javafx.scene.control.ListView; -import javafx.scene.image.ImageView; -import javafx.scene.layout.AnchorPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.VBox; -import javafx.beans.value.ChangeListener; - -import javafx.util.Callback; - -import java.util.concurrent.TimeUnit; +import javafx.collections.ObservableList; import static bisq.desktop.util.FormBuilder.add2ButtonsAfterGroup; import static bisq.desktop.util.FormBuilder.add3ButtonsAfterGroup; @@ -70,9 +59,7 @@ import static bisq.desktop.util.FormBuilder.addTopLabelListView; @FxmlView -public class AltCoinAccountsView extends ActivatableViewAndModel { - - private ListView paymentAccountsListView; +public class AltCoinAccountsView extends PaymentAccountsView { private final InputValidator inputValidator; private final AltCoinAddressValidator altCoinAddressValidator; @@ -82,9 +69,8 @@ public class AltCoinAccountsView extends ActivatableViewAndModel paymentAccountChangeListener; @Inject public AltCoinAccountsView(AltCoinAccountsViewModel model, @@ -103,32 +89,18 @@ public AltCoinAccountsView(AltCoinAccountsViewModel model, } @Override - public void initialize() { - buildForm(); - paymentAccountChangeListener = (observable, oldValue, newValue) -> { - if (newValue != null) - onSelectAccount(newValue); - }; - Label placeholder = new AutoTooltipLabel(Res.get("shared.noAccountsSetupYet")); - placeholder.setWrapText(true); - paymentAccountsListView.setPlaceholder(placeholder); + protected ObservableList getPaymentAccounts() { + return model.getPaymentAccounts(); } @Override - protected void activate() { - paymentAccountsListView.setItems(model.getPaymentAccounts()); - paymentAccountsListView.getSelectionModel().selectedItemProperty().addListener(paymentAccountChangeListener); - addAccountButton.setOnAction(event -> addNewAccount()); - exportButton.setOnAction(event -> model.dataModel.exportAccounts((Stage) root.getScene().getWindow())); - importButton.setOnAction(event -> model.dataModel.importAccounts((Stage) root.getScene().getWindow())); + protected void importAccounts() { + model.dataModel.importAccounts((Stage) root.getScene().getWindow()); } @Override - protected void deactivate() { - paymentAccountsListView.getSelectionModel().selectedItemProperty().removeListener(paymentAccountChangeListener); - addAccountButton.setOnAction(null); - exportButton.setOnAction(null); - importButton.setOnAction(null); + protected void exportAccounts() { + model.dataModel.exportAccounts((Stage) root.getScene().getWindow()); } /////////////////////////////////////////////////////////////////////////////////////////// @@ -188,8 +160,8 @@ private void onSaveNewAccount(PaymentAccount paymentAccount) { break; } - if (!model.getPaymentAccounts().stream().filter(e -> e.getAccountName() != null && - e.getAccountName().equals(paymentAccount.getAccountName())).findAny().isPresent()) { + if (model.getPaymentAccounts().stream().noneMatch(e -> e.getAccountName() != null && + e.getAccountName().equals(paymentAccount.getAccountName()))) { model.onSaveNewAccount(paymentAccount); removeNewAccountForm(); } else { @@ -202,62 +174,17 @@ private void onCancelNewAccount() { removeNewAccountForm(); } - private void onDeleteAccount(PaymentAccount paymentAccount) { - new Popup<>().warning(Res.get("shared.askConfirmDeleteAccount")) - .actionButtonText(Res.get("shared.yes")) - .onAction(() -> { - boolean isPaymentAccountUsed = model.onDeleteAccount(paymentAccount); - if (!isPaymentAccountUsed) - removeSelectAccountForm(); - else - UserThread.runAfter(() -> new Popup<>().warning( - Res.get("shared.cannotDeleteAccount")) - .show(), 100, TimeUnit.MILLISECONDS); - }) - .closeButtonText(Res.get("shared.cancel")) - .show(); - } - - /////////////////////////////////////////////////////////////////////////////////////////// // Base form /////////////////////////////////////////////////////////////////////////////////////////// - private void buildForm() { + protected void buildForm() { addTitledGroupBg(root, gridRow, 2, Res.get("shared.manageAccounts")); Tuple3, VBox> tuple = addTopLabelListView(root, gridRow, Res.get("account.altcoin.yourAltcoinAccounts"), Layout.FIRST_ROW_DISTANCE); paymentAccountsListView = tuple.second; paymentAccountsListView.setPrefHeight(2 * Layout.LIST_ROW_HEIGHT + 14); - paymentAccountsListView.setCellFactory(new Callback, ListCell>() { - @Override - public ListCell call(ListView list) { - return new ListCell() { - final Label label = new AutoTooltipLabel(); - final ImageView icon = ImageUtil.getImageViewById(ImageUtil.REMOVE_ICON); - final Button removeButton = new AutoTooltipButton("", icon); - final AnchorPane pane = new AnchorPane(label, removeButton); - - { - label.setLayoutY(5); - removeButton.setId("icon-button"); - AnchorPane.setRightAnchor(removeButton, 0d); - } - - @Override - public void updateItem(final PaymentAccount item, boolean empty) { - super.updateItem(item, empty); - if (item != null && !empty) { - label.setText(item.getAccountName()); - removeButton.setOnAction(e -> onDeleteAccount(item)); - setGraphic(pane); - } else { - setGraphic(null); - } - } - }; - } - }); + setPaymentAccountsCellFactory(); Tuple3 tuple3 = add3ButtonsAfterGroup(root, ++gridRow, Res.get("shared.addNewAccount"), Res.get("shared.ExportAccounts"), Res.get("shared.importAccounts")); @@ -267,7 +194,7 @@ public void updateItem(final PaymentAccount item, boolean empty) { } // Add new account form - private void addNewAccount() { + protected void addNewAccount() { paymentAccountsListView.getSelectionModel().clearSelection(); removeAccountRows(); addAccountButton.setDisable(true); @@ -291,10 +218,10 @@ private void addNewAccount() { } // Select account form - private void onSelectAccount(PaymentAccount paymentAccount) { + protected void onSelectAccount(PaymentAccount paymentAccount) { removeAccountRows(); addAccountButton.setDisable(false); - accountTitledGroupBg = addTitledGroupBg(root, ++gridRow, 1, Res.get("shared.selectedAccount"), Layout.GROUP_DISTANCE); + accountTitledGroupBg = addTitledGroupBg(root, ++gridRow, 2, Res.get("shared.selectedAccount"), Layout.GROUP_DISTANCE); paymentMethodForm = getPaymentMethodForm(paymentAccount); paymentMethodForm.addFormForDisplayAccount(); gridRow = paymentMethodForm.getGridRow(); @@ -329,17 +256,21 @@ private void removeNewAccountForm() { addAccountButton.setDisable(false); } - private void removeSelectAccountForm() { + @Override + protected void removeSelectAccountForm() { FormBuilder.removeRowsFromGridPane(root, 2, gridRow); gridRow = 1; addAccountButton.setDisable(false); paymentAccountsListView.getSelectionModel().clearSelection(); } + @Override + protected boolean deleteAccountFromModel(PaymentAccount paymentAccount) { + return model.onDeleteAccount(paymentAccount); + } private void removeAccountRows() { FormBuilder.removeRowsFromGridPane(root, 2, gridRow); gridRow = 1; } - } diff --git a/desktop/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsView.java b/desktop/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsView.java index 52347a5a11d..2a3b180d0a4 100644 --- a/desktop/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsView.java +++ b/desktop/src/main/java/bisq/desktop/main/account/content/fiataccounts/FiatAccountsView.java @@ -17,10 +17,7 @@ package bisq.desktop.main.account.content.fiataccounts; -import bisq.desktop.common.view.ActivatableViewAndModel; import bisq.desktop.common.view.FxmlView; -import bisq.desktop.components.AutoTooltipButton; -import bisq.desktop.components.AutoTooltipLabel; import bisq.desktop.components.TitledGroupBg; import bisq.desktop.components.paymentmethods.AliPayForm; import bisq.desktop.components.paymentmethods.CashAppForm; @@ -49,10 +46,10 @@ import bisq.desktop.components.paymentmethods.VenmoForm; import bisq.desktop.components.paymentmethods.WeChatPayForm; import bisq.desktop.components.paymentmethods.WesternUnionForm; +import bisq.desktop.main.account.content.PaymentAccountsView; import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.util.FormBuilder; import bisq.desktop.util.GUIUtil; -import bisq.desktop.util.ImageUtil; import bisq.desktop.util.Layout; import bisq.desktop.util.validation.AliPayValidator; import bisq.desktop.util.validation.BICValidator; @@ -88,7 +85,6 @@ import bisq.core.util.BSFormatter; import bisq.core.util.validation.InputValidator; -import bisq.common.UserThread; import bisq.common.util.Tuple2; import bisq.common.util.Tuple3; @@ -101,22 +97,16 @@ import javafx.scene.control.Button; import javafx.scene.control.ComboBox; import javafx.scene.control.Label; -import javafx.scene.control.ListCell; import javafx.scene.control.ListView; -import javafx.scene.image.ImageView; -import javafx.scene.layout.AnchorPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.VBox; -import javafx.beans.value.ChangeListener; - import javafx.collections.FXCollections; +import javafx.collections.ObservableList; -import javafx.util.Callback; import javafx.util.StringConverter; import java.util.List; -import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import static bisq.desktop.util.FormBuilder.add2ButtonsAfterGroup; @@ -125,7 +115,7 @@ import static bisq.desktop.util.FormBuilder.addTopLabelListView; @FxmlView -public class FiatAccountsView extends ActivatableViewAndModel { +public class FiatAccountsView extends PaymentAccountsView { private final IBANValidator ibanValidator; private final BICValidator bicValidator; @@ -149,13 +139,11 @@ public class FiatAccountsView extends ActivatableViewAndModel paymentAccountsListView; private ComboBox paymentMethodComboBox; private PaymentMethodForm paymentMethodForm; private TitledGroupBg accountTitledGroupBg; - private Button addAccountButton, saveNewAccountButton, exportButton, importButton; + private Button saveNewAccountButton; private int gridRow = 0; - private ChangeListener paymentAccountChangeListener; @Inject public FiatAccountsView(FiatAccountsViewModel model, @@ -208,35 +196,20 @@ public FiatAccountsView(FiatAccountsViewModel model, } @Override - public void initialize() { - buildForm(); - paymentAccountChangeListener = (observable, oldValue, newValue) -> { - if (newValue != null) - onSelectAccount(newValue); - }; - Label placeholder = new AutoTooltipLabel(Res.get("shared.noAccountsSetupYet")); - placeholder.setWrapText(true); - paymentAccountsListView.setPlaceholder(placeholder); + protected ObservableList getPaymentAccounts() { + return model.getPaymentAccounts(); } @Override - protected void activate() { - paymentAccountsListView.setItems(model.getPaymentAccounts()); - paymentAccountsListView.getSelectionModel().selectedItemProperty().addListener(paymentAccountChangeListener); - addAccountButton.setOnAction(event -> addNewAccount()); - exportButton.setOnAction(event -> model.dataModel.exportAccounts((Stage) root.getScene().getWindow())); - importButton.setOnAction(event -> model.dataModel.importAccounts((Stage) root.getScene().getWindow())); + protected void importAccounts() { + model.dataModel.importAccounts((Stage) root.getScene().getWindow()); } @Override - protected void deactivate() { - paymentAccountsListView.getSelectionModel().selectedItemProperty().removeListener(paymentAccountChangeListener); - addAccountButton.setOnAction(null); - exportButton.setOnAction(null); - importButton.setOnAction(null); + protected void exportAccounts() { + model.dataModel.exportAccounts((Stage) root.getScene().getWindow()); } - /////////////////////////////////////////////////////////////////////////////////////////// // UI actions /////////////////////////////////////////////////////////////////////////////////////////// @@ -301,7 +274,7 @@ private void onSaveNewAccount(PaymentAccount paymentAccount) { } private void doSaveNewAccount(PaymentAccount paymentAccount) { - if (model.getPaymentAccounts().stream().noneMatch(e -> e.getAccountName() != null && + if (getPaymentAccounts().stream().noneMatch(e -> e.getAccountName() != null && e.getAccountName().equals(paymentAccount.getAccountName()))) { model.onSaveNewAccount(paymentAccount); removeNewAccountForm(); @@ -314,62 +287,22 @@ private void onCancelNewAccount() { removeNewAccountForm(); } - private void onDeleteAccount(PaymentAccount paymentAccount) { - new Popup<>().warning(Res.get("shared.askConfirmDeleteAccount")) - .actionButtonText(Res.get("shared.yes")) - .onAction(() -> { - boolean isPaymentAccountUsed = model.onDeleteAccount(paymentAccount); - if (!isPaymentAccountUsed) - removeSelectAccountForm(); - else - UserThread.runAfter(() -> new Popup<>().warning( - Res.get("shared.cannotDeleteAccount")) - .show(), 100, TimeUnit.MILLISECONDS); - }) - .closeButtonText(Res.get("shared.cancel")) - .show(); + protected boolean deleteAccountFromModel(PaymentAccount paymentAccount) { + return model.onDeleteAccount(paymentAccount); } - /////////////////////////////////////////////////////////////////////////////////////////// // Base form /////////////////////////////////////////////////////////////////////////////////////////// - private void buildForm() { + @Override + protected void buildForm() { addTitledGroupBg(root, gridRow, 2, Res.get("shared.manageAccounts")); Tuple3, VBox> tuple = addTopLabelListView(root, gridRow, Res.get("account.fiat.yourFiatAccounts"), Layout.FIRST_ROW_DISTANCE); paymentAccountsListView = tuple.second; paymentAccountsListView.setPrefHeight(2 * Layout.LIST_ROW_HEIGHT + 14); - paymentAccountsListView.setCellFactory(new Callback, ListCell>() { - @Override - public ListCell call(ListView list) { - return new ListCell() { - final Label label = new AutoTooltipLabel(); - final ImageView icon = ImageUtil.getImageViewById(ImageUtil.REMOVE_ICON); - final Button removeButton = new AutoTooltipButton("", icon); - final AnchorPane pane = new AnchorPane(label, removeButton); - - { - label.setLayoutY(5); - removeButton.setId("icon-button"); - AnchorPane.setRightAnchor(removeButton, 0d); - } - - @Override - public void updateItem(final PaymentAccount item, boolean empty) { - super.updateItem(item, empty); - if (item != null && !empty) { - label.setText(item.getAccountName()); - removeButton.setOnAction(e -> onDeleteAccount(item)); - setGraphic(pane); - } else { - setGraphic(null); - } - } - }; - } - }); + setPaymentAccountsCellFactory(); Tuple3 tuple3 = add3ButtonsAfterGroup(root, ++gridRow, Res.get("shared.addNewAccount"), Res.get("shared.ExportAccounts"), Res.get("shared.importAccounts")); @@ -379,12 +312,13 @@ public void updateItem(final PaymentAccount item, boolean empty) { } // Add new account form - private void addNewAccount() { + @Override + protected void addNewAccount() { paymentAccountsListView.getSelectionModel().clearSelection(); removeAccountRows(); addAccountButton.setDisable(true); accountTitledGroupBg = addTitledGroupBg(root, ++gridRow, 2, Res.get("shared.createNewAccount"), Layout.GROUP_DISTANCE); - paymentMethodComboBox = FormBuilder.addComboBox(root, gridRow, Res.get("shared.paymentMethod"), Layout.FIRST_ROW_AND_GROUP_DISTANCE); + paymentMethodComboBox = FormBuilder.addComboBox(root, gridRow, Res.get("shared.paymentMethod"), Layout.FIRST_ROW_AND_GROUP_DISTANCE); paymentMethodComboBox.setPromptText(Res.get("shared.selectPaymentMethod")); paymentMethodComboBox.setVisibleRowCount(11); paymentMethodComboBox.setPrefWidth(250); @@ -395,7 +329,7 @@ private void addNewAccount() { .filter(paymentMethod -> !paymentMethod.getId().equals(PaymentMethod.OK_PAY_ID)) .collect(Collectors.toList()); paymentMethodComboBox.setItems(FXCollections.observableArrayList(list)); - paymentMethodComboBox.setConverter(new StringConverter() { + paymentMethodComboBox.setConverter(new StringConverter<>() { @Override public String toString(PaymentMethod paymentMethod) { return paymentMethod != null ? Res.get(paymentMethod.getId()) : ""; @@ -409,7 +343,7 @@ public PaymentMethod fromString(String s) { paymentMethodComboBox.setOnAction(e -> { if (paymentMethodForm != null) { FormBuilder.removeRowsFromGridPane(root, 3, paymentMethodForm.getGridRow() + 1); - GridPane.setRowSpan(accountTitledGroupBg, paymentMethodForm.getRowSpan() + 2); + GridPane.setRowSpan(accountTitledGroupBg, paymentMethodForm.getRowSpan() + 1); } gridRow = 2; paymentMethodForm = getPaymentMethodForm(paymentMethodComboBox.getSelectionModel().getSelectedItem()); @@ -422,13 +356,14 @@ public PaymentMethod fromString(String s) { saveNewAccountButton.disableProperty().bind(paymentMethodForm.allInputsValidProperty().not()); Button cancelButton = tuple2.second; cancelButton.setOnAction(event -> onCancelNewAccount()); - GridPane.setRowSpan(accountTitledGroupBg, paymentMethodForm.getRowSpan() + 2); + GridPane.setRowSpan(accountTitledGroupBg, paymentMethodForm.getRowSpan() + 1); } }); } // Select account form - private void onSelectAccount(PaymentAccount paymentAccount) { + @Override + protected void onSelectAccount(PaymentAccount paymentAccount) { removeAccountRows(); addAccountButton.setDisable(false); accountTitledGroupBg = addTitledGroupBg(root, ++gridRow, 2, Res.get("shared.selectedAccount"), Layout.GROUP_DISTANCE); @@ -441,7 +376,7 @@ private void onSelectAccount(PaymentAccount paymentAccount) { deleteAccountButton.setOnAction(event -> onDeleteAccount(paymentMethodForm.getPaymentAccount())); Button cancelButton = tuple.second; cancelButton.setOnAction(event -> removeSelectAccountForm()); - GridPane.setRowSpan(accountTitledGroupBg, paymentMethodForm.getRowSpan() + 1); + GridPane.setRowSpan(accountTitledGroupBg, paymentMethodForm.getRowSpan()); model.onSelectAccount(paymentAccount); } } @@ -527,7 +462,8 @@ private void removeNewAccountForm() { addAccountButton.setDisable(false); } - private void removeSelectAccountForm() { + @Override + protected void removeSelectAccountForm() { FormBuilder.removeRowsFromGridPane(root, 2, gridRow); gridRow = 1; addAccountButton.setDisable(false); diff --git a/desktop/src/main/java/bisq/desktop/util/FormBuilder.java b/desktop/src/main/java/bisq/desktop/util/FormBuilder.java index 6307d85a5ad..4d95bd6bc63 100644 --- a/desktop/src/main/java/bisq/desktop/util/FormBuilder.java +++ b/desktop/src/main/java/bisq/desktop/util/FormBuilder.java @@ -800,18 +800,13 @@ public static ComboBox addComboBox(GridPane gridPane, int rowIndex, Strin // Label + SearchComboBox /////////////////////////////////////////////////////////////////////////////////////////// - public static Tuple2> addLabelSearchComboBox(GridPane gridPane, int rowIndex, String title, double top) { - Label label = null; - if (title != null) - label = addLabel(gridPane, rowIndex, title, top); + public static Tuple2> addLabelSearchComboBox(GridPane gridPane, int rowIndex, String title, double top) { SearchComboBox comboBox = new SearchComboBox<>(); - GridPane.setRowIndex(comboBox, rowIndex); - GridPane.setColumnIndex(comboBox, 1); - GridPane.setMargin(comboBox, new Insets(top, 0, 0, 0)); - gridPane.getChildren().add(comboBox); - return new Tuple2<>(label, comboBox); + final Tuple2 labelVBoxTuple2 = addTopLabelWithVBox(gridPane, rowIndex, title, comboBox, top); + + return new Tuple2<>(labelVBoxTuple2.first, comboBox); }