From 10347ae4884adbee190636a68f0ba2e7edbf2304 Mon Sep 17 00:00:00 2001 From: woodser Date: Sat, 12 Jul 2025 10:43:23 -0400 Subject: [PATCH] restore last combo box selection on focus out --- .../components/AutocompleteComboBox.java | 33 ++++++++++++++++++- .../TraditionalAccountsView.java | 2 ++ .../main/market/trades/TradesChartsView.java | 8 ++--- .../main/offer/offerbook/OfferBookView.java | 4 +-- 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/desktop/src/main/java/haveno/desktop/components/AutocompleteComboBox.java b/desktop/src/main/java/haveno/desktop/components/AutocompleteComboBox.java index e6701cdb4c..e6ef5dca7c 100644 --- a/desktop/src/main/java/haveno/desktop/components/AutocompleteComboBox.java +++ b/desktop/src/main/java/haveno/desktop/components/AutocompleteComboBox.java @@ -46,6 +46,7 @@ public class AutocompleteComboBox extends JFXComboBox { private List matchingList; private JFXComboBoxListViewSkin comboBoxListViewSkin; private boolean selectAllShortcut = false; + private T lastCommittedValue; public AutocompleteComboBox() { this(FXCollections.observableArrayList()); @@ -59,6 +60,30 @@ public class AutocompleteComboBox extends JFXComboBox { fixSpaceKey(); setAutocompleteItems(items); reactToQueryChanges(); + + // Store last committed value so we can restore it if nothing selected + valueProperty().addListener((obs, oldVal, newVal) -> { + if (newVal != null) + lastCommittedValue = newVal; + }); + + // Restore last committed value when editor loses focus if no matches + getEditor().focusedProperty().addListener((obs, wasFocused, isNowFocused) -> { + if (!isNowFocused) { + String input = getEditor().getText(); + T matched = getConverter().fromString(input); + + boolean matchFound = getItems().stream() + .anyMatch(item -> item.equals(matched)); + + if (!matchFound) { + UserThread.execute(() -> { + getSelectionModel().select(lastCommittedValue); + getEditor().setText(asString(lastCommittedValue)); + }); + } + } + }); } /** @@ -100,10 +125,16 @@ public class AutocompleteComboBox extends JFXComboBox { return; } - // Case 2: fire if the text is empty to support special "show all" case + // Case 2: fire if the text is empty if (inputText.isEmpty()) { eh.handle(e); getParent().requestFocus(); + + // Restore the last committed value + UserThread.execute(() -> { + getSelectionModel().select(lastCommittedValue); + getEditor().setText(asString(lastCommittedValue)); + }); } }); } diff --git a/desktop/src/main/java/haveno/desktop/main/account/content/traditionalaccounts/TraditionalAccountsView.java b/desktop/src/main/java/haveno/desktop/main/account/content/traditionalaccounts/TraditionalAccountsView.java index 3a758f1657..b6e8a575bc 100644 --- a/desktop/src/main/java/haveno/desktop/main/account/content/traditionalaccounts/TraditionalAccountsView.java +++ b/desktop/src/main/java/haveno/desktop/main/account/content/traditionalaccounts/TraditionalAccountsView.java @@ -501,6 +501,8 @@ public class TraditionalAccountsView extends PaymentAccountsView { + if (paymentMethodComboBox.getEditor().getText().isEmpty()) + return; if (paymentMethodForm != null) { FormBuilder.removeRowsFromGridPane(root, 3, paymentMethodForm.getGridRow() + 1); GridPane.setRowSpan(accountTitledGroupBg, paymentMethodForm.getRowSpan() + 1); diff --git a/desktop/src/main/java/haveno/desktop/main/market/trades/TradesChartsView.java b/desktop/src/main/java/haveno/desktop/main/market/trades/TradesChartsView.java index bb75c80684..d087329942 100644 --- a/desktop/src/main/java/haveno/desktop/main/market/trades/TradesChartsView.java +++ b/desktop/src/main/java/haveno/desktop/main/market/trades/TradesChartsView.java @@ -116,15 +116,11 @@ public class TradesChartsView extends ActivatableViewAndModel currencyItem.codeDashNameString().equals(query)). findAny().orElse(null); } - - private CurrencyListItem specialShowAllItem() { - return comboBox.getItems().get(0); - } } private final User user; @@ -291,7 +287,7 @@ public class TradesChartsView extends ActivatableViewAndModel UserThread.execute(() -> { if (currencyComboBox.getEditor().getText().isEmpty()) - currencyComboBox.getSelectionModel().select(SHOW_ALL); + return; CurrencyListItem selectedItem = currencyComboBox.getSelectionModel().getSelectedItem(); if (selectedItem != null) { model.onSetTradeCurrency(selectedItem.tradeCurrency); diff --git a/desktop/src/main/java/haveno/desktop/main/offer/offerbook/OfferBookView.java b/desktop/src/main/java/haveno/desktop/main/offer/offerbook/OfferBookView.java index d10e6b6562..2129f3c6dc 100644 --- a/desktop/src/main/java/haveno/desktop/main/offer/offerbook/OfferBookView.java +++ b/desktop/src/main/java/haveno/desktop/main/offer/offerbook/OfferBookView.java @@ -347,7 +347,7 @@ abstract public class OfferBookView { if (currencyComboBox.getEditor().getText().isEmpty()) - currencyComboBox.getSelectionModel().select(SHOW_ALL); + return; model.onSetTradeCurrency(currencyComboBox.getSelectionModel().getSelectedItem()); paymentMethodComboBox.setAutocompleteItems(model.getPaymentMethods()); model.updateSelectedPaymentMethod(); @@ -500,7 +500,7 @@ abstract public class OfferBookView asString(item).equals(query)). findAny().orElse(null);