Skip to content

Commit

Permalink
Merge pull request #22 from gldiazcardenas/issues-2-and-4-javadocs-ke…
Browse files Browse the repository at this point in the history
…yboard

[Issues-2-4] Keyboard support and Javadocs
  • Loading branch information
dlemmermann authored Nov 28, 2023
2 parents c87fdd7 + 562a17a commit 9bee3cc
Showing 1 changed file with 100 additions and 45 deletions.
145 changes: 100 additions & 45 deletions phonenumberfx/src/main/java/com/dlsc/phonenumberfx/PhoneNumberField.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ public class PhoneNumberField extends CustomTextField {
}

private static final Comparator<Country> 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);
};

Expand Down Expand Up @@ -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();
}
};
Expand All @@ -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<Country> comboBoxSkin = (ComboBoxListViewSkin<Country>) comboBox.getSkin();
ListView<Country> listView = (ListView<Country>) 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();
Expand Down Expand Up @@ -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() {
Expand All @@ -347,6 +340,8 @@ public final void setRawPhoneNumber(String rawPhoneNumber) {
rawPhoneNumberProperty().set(rawPhoneNumber);
}

// SELECTED COUNTRY

private final ObjectProperty<Country> selectedCountry = new SimpleObjectProperty<>(this, "selectedCountry") {
private boolean selfUpdate;

Expand All @@ -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.
*/
Expand All @@ -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();
}
Expand All @@ -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();
}
Expand All @@ -423,6 +424,10 @@ private void setE164PhoneNumber(String e164PhoneNumber) {

private final ReadOnlyObjectWrapper<Phonenumber.PhoneNumber> 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<Phonenumber.PhoneNumber> phoneNumberProperty() {
return phoneNumber.getReadOnlyProperty();
}
Expand All @@ -440,7 +445,7 @@ private void setPhoneNumber(Phonenumber.PhoneNumber phoneNumber) {
private final ListProperty<Country> 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<Country> availableCountriesProperty() {
Expand All @@ -460,7 +465,7 @@ public final void setAvailableCountries(ObservableList<Country> availableCountri
private final ListProperty<Country> 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.
*/
Expand All @@ -481,7 +486,7 @@ public final void setPreferredCountries(ObservableList<Country> 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() {
Expand All @@ -501,7 +506,7 @@ public final void setDisableCountryDropdown(boolean disableCountryDropdown) {
private final ObjectProperty<Callback<ListView<Country>, ListCell<Country>>> 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<Callback<ListView<Country>, ListCell<Country>>> countryCellFactoryProperty() {
return countryCellFactory;
Expand All @@ -520,7 +525,7 @@ public final void setCountryCellFactory(Callback<ListView<Country>, ListCell<Cou
private final ReadOnlyBooleanWrapper valid = new ReadOnlyBooleanWrapper(this, "valid");

/**
* Read-only property that indicates whether the phone number is valid or not.
* @return Read-only property that indicates whether the phone number is valid or not.
*/
public final ReadOnlyBooleanProperty validProperty() {
return valid.getReadOnlyProperty();
Expand Down Expand Up @@ -565,7 +570,7 @@ private boolean isExpectedTypeMatch(Phonenumber.PhoneNumber number) {
private final BooleanProperty countryCodeVisible = new SimpleBooleanProperty(this, "countryCodeVisible");

/**
* Determines if the country code stays visible in the field or if it gets removed as soon as
* @return Determines if the country code stays visible in the field or if it gets removed as soon as
* the field has determined which country it is.
*/
public final BooleanProperty countryCodeVisibleProperty() {
Expand All @@ -580,6 +585,44 @@ public final void setCountryCodeVisible(boolean countryCodeVisible) {
countryCodeVisibleProperty().set(countryCodeVisible);
}

// SHOW COUNTRY DROPDOWN

private final BooleanProperty showCountryDropdown = new SimpleBooleanProperty(this, "showCountryDropdown", true);

/**
* @return The property indicating whether the country dropdown is visible or not.
*/
public final BooleanProperty showCountryDropdownProperty() {
return showCountryDropdown;
}

public final boolean isShowCountryDropdown() {
return showCountryDropdown.get();
}

public final void setShowCountryDropdown(boolean showCountryDropdown) {
this.showCountryDropdown.set(showCountryDropdown);
}

// SHOW EXAMPLE NUMBERS

private final BooleanProperty showExampleNumbers = new SimpleBooleanProperty(this, "showExampleNumbers", true);

/**
* @return The property that allows to show/hide prompt text with phone number examples after selecting the country.
*/
public final BooleanProperty showExampleNumbersProperty() {
return showExampleNumbers;
}

public final boolean isShowExampleNumbers() {
return showExampleNumbers.get();
}

public final void setShowExampleNumbers(boolean showExampleNumbers) {
this.showExampleNumbers.set(showExampleNumbers);
}

/**
* All countries supported by the control.
*/
Expand Down Expand Up @@ -859,6 +902,9 @@ public String iso2Code() {
return iso2Code;
}

/**
* @return The phone number prefix including only the country code with (+) sign.
*/
public String countryCodePrefix() {
return "+" + countryCode();
}
Expand All @@ -872,9 +918,18 @@ public Integer defaultAreaCode() {
return areaCodes().length > 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();
}

}

/**
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit 9bee3cc

Please sign in to comment.