diff --git a/phonenumberfx/src/main/java/com/dlsc/phonenumberfx/PhoneNumberField.java b/phonenumberfx/src/main/java/com/dlsc/phonenumberfx/PhoneNumberField.java index 4d6612f..19a66fa 100644 --- a/phonenumberfx/src/main/java/com/dlsc/phonenumberfx/PhoneNumberField.java +++ b/phonenumberfx/src/main/java/com/dlsc/phonenumberfx/PhoneNumberField.java @@ -57,8 +57,8 @@ public class PhoneNumberField extends CustomTextField { } private static final Comparator NAME_SORT_ASC = (c1, c2) -> { - String c1Name = new Locale("en", c1.iso2Code()).getDisplayCountry(); - String c2Name = new Locale("en", c2.iso2Code()).getDisplayCountry(); + String c1Name = c1.countryName(); + String c2Name = c2.countryName(); return c1Name.compareTo(c2Name); }; @@ -110,8 +110,8 @@ protected void layoutChildren(double x, double y, double w, double h) { // use same bounds for globe that were computed for the button cell this.globeButton.resizeRelocate(bounds.getMinX(), bounds.getMinY(), bounds.getWidth(), bounds.getHeight()); - this.globeButton.setVisible(getValue() == null); - this.globeButton.setManaged(getValue() == null); + this.globeButton.setVisible(getSkinnable().getValue() == null); + this.globeButton.setManaged(getSkinnable().getValue() == null); this.globeButton.toFront(); } }; @@ -133,6 +133,30 @@ protected void layoutChildren(double x, double y, double w, double h) { setLeft(comboBox); + addEventFilter(KeyEvent.KEY_PRESSED, evt -> { + if (evt.getCode().isLetterKey()) { + String letter = evt.getCode().getChar(); + + ComboBoxListViewSkin comboBoxSkin = (ComboBoxListViewSkin) comboBox.getSkin(); + ListView listView = (ListView) comboBoxSkin.getPopupContent(); + + Country country = countries + .stream() + .filter(c -> c.countryName().startsWith(letter)) + .findFirst() + .orElse(null); + + if (country != null) { + if (!comboBox.isShowing()) { + comboBox.show(); + } + + listView.requestFocus(); + listView.scrollTo(country); + } + } + }); + phoneNumberUtil = PhoneNumberUtil.getInstance(); resolver = new CountryResolver(); formatter = new PhoneNumberFormatter(); @@ -298,41 +322,10 @@ public void set(String newRawPhoneNumber) { } }; - private final BooleanProperty showCountryDropdown = new SimpleBooleanProperty(this, "showCountryDropdown", true); - - public final boolean isShowCountryDropdown() { - return showCountryDropdown.get(); - } - - /** - * Returns the property indicating whether the country dropdown is visible or not. - * - * @return the showCountryDropdown property - */ - public final BooleanProperty showCountryDropdownProperty() { - return showCountryDropdown; - } - - public final void setShowCountryDropdown(boolean showCountryDropdown) { - this.showCountryDropdown.set(showCountryDropdown); - } - - private final BooleanProperty showExampleNumbers = new SimpleBooleanProperty(this, "showExampleNumbers", true); - - public final boolean isShowExampleNumbers() { - return showExampleNumbers.get(); - } - - public final BooleanProperty showExampleNumbersProperty() { - return showExampleNumbers; - } - - public final void setShowExampleNumbers(boolean showExampleNumbers) { - this.showExampleNumbers.set(showExampleNumbers); - } + // RAW PHONE NUMBER /** - * The raw phone number corresponding exactly to what the user typed in, including the (+) sign appended at the + * @return The raw phone number corresponding exactly to what the user typed in, including the (+) sign appended at the * beginning. This value can be a valid E164 formatted number. */ public final StringProperty rawPhoneNumberProperty() { @@ -347,6 +340,8 @@ public final void setRawPhoneNumber(String rawPhoneNumber) { rawPhoneNumberProperty().set(rawPhoneNumber); } + // SELECTED COUNTRY + private final ObjectProperty selectedCountry = new SimpleObjectProperty<>(this, "selectedCountry") { private boolean selfUpdate; @@ -371,7 +366,7 @@ public void set(Country newCountry) { }; /** - * The selected country. Use this property if you want to define a default (pre-selected) country. + * @return The selected country. Use this property if you want to define a default (pre-selected) country. * It can also be used in conjunction with {@link #disableCountryDropdownProperty()} to avoid * changing the country part. */ @@ -391,6 +386,9 @@ public final void setSelectedCountry(Country selectedCountry) { private final ReadOnlyStringWrapper nationalPhoneNumber = new ReadOnlyStringWrapper(this, "nationalPhoneNumber"); + /** + * @return The {@link #phoneNumberProperty() phone number} formatted as a national number without the country code. + */ public final ReadOnlyStringProperty nationalPhoneNumberProperty() { return nationalPhoneNumber.getReadOnlyProperty(); } @@ -407,6 +405,9 @@ private void setNationalPhoneNumber(String nationalPhoneNumber) { private final ReadOnlyStringWrapper e164PhoneNumber = new ReadOnlyStringWrapper(this, "e164PhoneNumber"); + /** + * @return The {@link #phoneNumberProperty() phone number} formatted as E164 standard format including the country code and national number. + */ public final ReadOnlyStringProperty e164PhoneNumberProperty() { return e164PhoneNumber.getReadOnlyProperty(); } @@ -423,6 +424,10 @@ private void setE164PhoneNumber(String e164PhoneNumber) { private final ReadOnlyObjectWrapper phoneNumber = new ReadOnlyObjectWrapper<>(this, "phoneNumber"); + /** + * @return The phone number parsed out from the {@link #rawPhoneNumberProperty() raw phone number}, this might be {@code null} if the + * phone number is not a valid one. + */ public final ReadOnlyObjectProperty phoneNumberProperty() { return phoneNumber.getReadOnlyProperty(); } @@ -440,7 +445,7 @@ private void setPhoneNumber(Phonenumber.PhoneNumber phoneNumber) { private final ListProperty availableCountries = new SimpleListProperty<>(FXCollections.observableArrayList()); /** - * The list of available countries from which the user can select one and put it into the + * @return The list of available countries from which the user can select one and put it into the * {@link #selectedCountryProperty()}. */ public final ListProperty availableCountriesProperty() { @@ -460,7 +465,7 @@ public final void setAvailableCountries(ObservableList availableCountri private final ListProperty preferredCountries = new SimpleListProperty<>(FXCollections.observableArrayList()); /** - * The list of preferred countries that are shown first in the list of available countries. If a country + * @return The list of preferred countries that are shown first in the list of available countries. If a country * is added to this list that is not present in the {@link #getAvailableCountries()} then it will be ignored * and not shown. */ @@ -481,7 +486,7 @@ public final void setPreferredCountries(ObservableList preferredCountri private final BooleanProperty disableCountryDropdown = new SimpleBooleanProperty(this, "disableCountryDropdown"); /** - * Flag to disable the country dropdown. This will allow to specify a default country and avoid changing it + * @return Flag to disable the country dropdown. This will allow to specify a default country and avoid changing it * in case it is wanted to be fixed. */ public final BooleanProperty disableCountryDropdownProperty() { @@ -501,7 +506,7 @@ public final void setDisableCountryDropdown(boolean disableCountryDropdown) { private final ObjectProperty, ListCell>> countryCellFactory = new SimpleObjectProperty<>(this, "countryCellFactory", listView -> new CountryCell()); /** - * Factory that allows to replace the list cells used to graphically represent each country. + * @return Factory that allows to replace the list cells used to graphically represent each country. */ public final ObjectProperty, ListCell>> countryCellFactoryProperty() { return countryCellFactory; @@ -520,7 +525,7 @@ public final void setCountryCellFactory(Callback, ListCell 0 ? areaCodes()[0] : null; } + /** + * The phone number prefix including the country and default area code if any. + * @return The phone number prefix. + */ public String phonePrefix() { return countryCodePrefix() + Optional.ofNullable(defaultAreaCode()).map(Object::toString).orElse(""); } + + private String countryName() { + return new Locale("en", iso2Code).getDisplayCountry(); + } + } /** @@ -1102,7 +1157,7 @@ protected void updateItem(Country country, boolean empty) { int index = -1; if (country != null && !empty) { - setText(new Locale("en", country.iso2Code()).getDisplayCountry()); + setText(country.countryName()); setGraphic(getCountryGraphic(country)); index = getPreferredCountries().indexOf(country); } else {