public class PhoneNumberField

  1. Object
  2. Component
  3. Container
  4. PhoneNumberField

ImplementsAnimation, Editable, Iterable<Component>, StyleListener

A phone number entry field: a country selector holding the calling code and a field for the rest of the number, producing one E.164 string.

Example

PhoneNumberField phone = new PhoneNumberField();
form.add(phone);
sendButton.addActionListener(e -> requestCode(phone.getE164()));

The selector starts on the country the device is in and opens a searchable list of every calling code. The number field carries TextArea#PHONENUMBER, so it gets the phone keypad and the platform offers the device’s own number where it knows it.

The value

#getE164() returns the number in the one format a server can act on – a leading “+”, the calling code, then the national number, digits only:

Everything that is not a digit is dropped, so the separators a user reaches for make no difference:

phone.setCountry(PhoneNumberField.findCountry("IL"));
// user types 50-123-4567, or 50 123 4567, or (50) 1234567
phone.getE164(); // "+972501234567"

A number that already carries its own calling code is used as it stands, and the selector is not applied to it. Pasting is one way that happens; platform autofill is the other, since it offers the device’s own number in exactly that form:

// Israel selected, the user pastes +1 415 555 0100
phone.getE164(); // "+14155550100", not the selection with that appended

A national trunk prefix is a digit, and it is kept:

// the same user typing the number the way they say it out loud
// user types 050-123-4567
phone.getE164(); // "+9720501234567" -- the leading 0 is still there

That is not an oversight, and it is the one thing to handle before sending. “0” is a trunk prefix in Israel and part of the number in Italy, and telling them apart is a per-country rule this field does not carry, so stripping one here would corrupt numbers in the countries where it belongs. Normalizing is left to the service that sends the message, which has the rules and can refuse what it cannot make sense of.

What this field does carry is the shape of E.164 – at most fifteen digits, and the calling code separated from the rest – so #isValid() is a sanity check rather than a verdict.

Country names

Names are English, and each is looked up first as “Country.” plus the ISO code in the theme’s resource bundle, so an application that ships translations gets them without replacing the list. An application with its own list entirely passes it to #setCountries(Country[]).

Styling

The field uses the UIID “PhoneNumberField”, the country selector “PhoneNumberCountry” and the number field “PhoneNumberText”.

Nested types

class PhoneNumberField.CountryA country and its E.164 calling code.

Constructors

public PhoneNumberField()Builds a field defaulting to the country the device reports, falling back to the first entry when the device reports one that is not in the list.

Methods

public PhoneNumberField.Country[] getCountries()The list this field offers, defaulting to every known country.
public void setCountries(PhoneNumberField.Country[] countries)Narrows or replaces the list this field offers.
public PhoneNumberField.Country getCountry()The selected country, never null.
public void setCountry(PhoneNumberField.Country c)Selects a country, which changes the calling code the value is built from without touching the number that was typed.
public String getNationalNumber()The national part as typed, digits only.
public String getE164()The number in E.164 form – “+”, the calling code, then the national number – or null when nothing has been typed.
public void setE164(String e164)Sets the field from an E.164 number, selecting the country whose calling code the number starts with and putting the rest in the number field.
public boolean isValid()A sanity check on the shape of the number: a national part that is present and short enough to leave the whole number inside E.164’s fifteen digit limit.
public TextField getNumberField()The field holding the national part, exposed for theming and for listening to what is typed.
public Button getCountryButton()The button that opens the country list, exposed for theming.
public void addDataChangedListener(DataChangedListener l)Adds a listener notified as the number is typed.
public void removeDataChangedListener(DataChangedListener l)Removes a previously-registered listener.
public static PhoneNumberField.Country[] getAllCountries()Every country with a numbering plan of its own, ordered by English name.
public static PhoneNumberField.Country findCountry(String isoCode)Looks a country up by its two letter ISO 3166 code.

Inherited fields

Inherited methods

From Container

encloseIn, encloseIn, initLaf, getUIManager, setUIManager, isSurface, add, addAll, add, add, add, add, add, getLeadComponent, setLeadComponent, getLeadParent, keyPressed, keyReleased, getLayout, setLayout, invalidate, setShouldLayout, setShouldCalcPreferredSize, getLayoutWidth, getLayoutHeight, applyRTL, constrainWidthWhenScrollable, constrainHeightWhenScrollable, addComponent, addComponent, addComponent, addComponent, replaceAndWait, replaceAndWait, replace, replaceAndWait, replace, createReplaceTransition, isEnabled, setEnabled, removeComponent, cancelRepaints, flushReplace, removeAll, revalidateWithAnimationSafety, revalidate, revalidateLater, forceRevalidate, clearClientProperties, paint, paintGlass, layoutContainer, isSafeArea, setSafeArea, isSafeAreaRoot, getSafeAreaRoot, setSafeAreaRoot, getComponentCount, getComponentAt, getComponentIndex, contains, scrollComponentToVisible, getClosestComponentTo, getResponderAt, getComponentAt, findDropTargetAt, pointerPressed, calcPreferredSize, paramString, refreshTheme, isScrollableX, setScrollableX, isScrollableY, setScrollableY, getSideGap, getBottomGap, setScrollable, setCellRenderer, getScrollIncrement, setScrollIncrement, findFirstFocusable, dragInitiated, fireClicked, isSelectableInteraction, getGridPosY, paintComponentBackground, getGridPosX, animateHierarchyAndWait, createAnimateHierarchy, animateHierarchy, animateHierarchyFadeAndWait, createAnimateHierarchyFade, animateHierarchyFade, animateLayoutFadeAndWait, createAnimateLayoutFadeAndWait, animateLayoutFade, createAnimateLayoutFade, animateLayoutAndWait, animateLayout, updateTabIndices, createAnimateLayout, drop, createAnimateMotion, morph, morphAndWait, animateUnlayout, animateUnlayoutAndWait, createAnimateUnlayout, getChildrenAsList, iterator, iterator

From Component

setSameSize, isSetCursorSupported, parsePreferredSize, getDefaultDragTransparency, setDefaultDragTransparency, getEditingDelegate, setEditingDelegate, getCursor, setCursor, showNativeOverlay, hideNativeOverlay, updateNativeOverlay, getNativeOverlay, getAllStyles, getSameWidth, setSameWidth, getSameHeight, setSameHeight, getX, setX, getOuterX, getInnerX, getY, setY, getOuterY, getInnerY, isVisible, setVisible, getClientProperty, stripMarginAndPadding, putClientProperty, getDirtyRegion, setDirtyRegion, isOpaque, setOpaque, getWidth, setWidth, getOuterWidth, getInnerWidth, getHeight, setHeight, getOuterHeight, getInnerHeight, isDragRegion, getDragRegionStatus, getBaseline, getBaselineResizeBehavior, getPreferredSizeStr, setPreferredSizeStr, getPreferredSize, setPreferredSize, getScrollDimension, calcScrollSize, setScrollSize, getPreferredW, setPreferredW, getPreferredH, setPreferredH, getOuterPreferredH, getInnerPreferredH, getOuterPreferredW, getInnerPreferredW, setSize, getUIID, setUIID, setUIIDFinal, setUIID, getInlineAllStyles, setInlineAllStyles, getInlineSelectedStyles, setInlineSelectedStyles, getInlineUnselectedStyles, setInlineUnselectedStyles, getInlineDisabledStyles, setInlineDisabledStyles, getInlinePressedStyles, setInlinePressedStyles, remove, getParent, getOwner, setOwner, isOwnedBy, containsOrOwns, addFocusListener, removeFocusListener, addScrollListener, removeScrollListener, getSelectCommandText, setSelectCommandText, getLabelForComponent, setLabelForComponent, focusGained, focusLost, paintBackgrounds, paintShadows, getAbsoluteX, getAbsoluteY, isInClippingRegion, paintIntersectingComponentsAbove, paintScrollbars, paintScrollbarX, getScrollOpacity, getSelectedRect, paintScrollbarY, paintComponent, paintComponent, getBorder, getScrollable, paintBackground, isScrollable, getScrollX, setScrollX, getScrollY, setScrollY, onScrollX, onScrollY, getDraggedx, getDraggedy, contains, visibleBoundsContains, hasFixedPreferredSize, getBounds, getBounds, getVisibleBounds, getVisibleBounds, isFocusable, setFocusable, onSetFocusable, resetFocusable, getTabIndex, setTabIndex, getPreferredTabIndex, setPreferredTabIndex, isTraversable, setTraversable, handlesInput, setHandlesInput, consumesRawTextInput, hasFocus, setFocus, getComponentForm, getTopLevelContainer, repaint, repaint, longKeyPress, keyRepeated, registerForAnimation, deregisterFromAnimation, getAnimationManager, getScrollAnimationSpeed, setScrollAnimationSpeed, isBlockLead, setBlockLead, isIgnorePointerEvents, setIgnorePointerEvents, isRippleEffect, setRippleEffect, getInlineStylesTheme, setInlineStylesTheme, shouldRenderComponentSelection, isHideInLandscape, setHideInLandscape, createStyleAnimation, isSmoothScrolling, setSmoothScrolling, pointerHover, stopScrollMomentum, pointerHoverReleased, pointerHoverPressed, pinch, pinchReleased, pinch, rotation, isPinchBlocksDragAndDrop, setPinchBlocksDragAndDrop, pointerDragged, getDragImage, getDragTransparency, setDragTransparency, toImage, drawDraggedImage, draggingOver, dragEnter, dragExit, addPullToRefresh, setPullToRefresh, respondsToPointerEvents, pointerDragged, isStickyDrag, pointerPressed, isDragAndDropOperation, pointerReleased, longPointerPress, pointerReleased, setVerticalScrollBounds, setHorizontalScrollBounds, isVScrollThumbGrabbed, isHScrollThumbGrabbed, isVScrollThumbHover, isHScrollThumbHover, isTensileDragEnabled, setTensileDragEnabled, getTextSelectionSupport, addDropListener, removeDropListener, addDragOverListener, removeDragOverListener, isNativeDragSource, setNativeDragSource, getNativeDragOperation, setNativeDragOperation, createNativeDragOperation, isNativeDropTarget, setNativeDropTarget, getAcceptedDropMimeTypes, setAcceptedDropMimeTypes, getAcceptedDropActions, setAcceptedDropActions, canAcceptNativeDrop, nativeDragEnter, nativeDragOver, nativeDragExit, nativeDrop, addNativeDropListener, removeNativeDropListener, addNativeDragOverListener, removeNativeDragOverListener, dragFinished, addDragFinishedListener, addStateChangeListener, removeStateChangeListener, addPointerPressedListener, addLongPressListener, addContextMenuListener, removeContextMenuListener, addMouseWheelListener, removeMouseWheelListener, addStylusListener, removeStylusListener, mouseWheel, paintRippleOverlay, removePointerPressedListener, removeLongPressListener, removeDragFinishedListener, addPointerReleasedListener, removePointerReleasedListener, addPointerDraggedListener, removePointerDraggedListener, getDragSpeed, getStyle, getPressedStyle, setPressedStyle, initUnselectedStyle, initPressedStyle, initDisabledStyle, initSelectedStyle, getUnselectedStyle, setUnselectedStyle, getSelectedStyle, setSelectedStyle, getDisabledStyle, setDisabledStyle, installDefaultPainter, requestFocus, toString, refreshTheme, refreshTheme, isDragActivated, animate, scrollRectToVisible, scrollRectToVisible, paintBorder, paintBorderBackground, isCellRenderer, isScrollVisible, setScrollVisible, setIsScrollVisible, startEditingAsync, stopEditing, isEditing, isEditable, laidOut, deinitialize, initComponent, isInitialized, setInitialized, styleChanged, getNextFocusDown, setNextFocusDown, getNextFocusUp, setNextFocusUp, getNextFocusLeft, setNextFocusLeft, getNextFocusRight, setNextFocusRight, getName, setName, initCustomStyle, deinitializeCustomStyle, isRTL, setRTL, isTactileTouch, isTactileTouch, setTactileTouch, getPropertyNames, getPropertyTypes, getPropertyTypeNames, getPropertyValue, setPropertyValue, paintLockRelease, paintLock, isSnapToGrid, setSnapToGrid, shouldBlockSideSwipe, shouldBlockSideSwipeLeft, shouldBlockSideSwipeRight, blocksSideSwipe, isFlatten, setFlatten, getTensileLength, setTensileLength, isGrabsPointerEvents, setGrabsPointerEvents, getScrollOpacityChangeSpeed, setScrollOpacityChangeSpeed, growShrink, isAlwaysTensile, setAlwaysTensile, isDraggable, setDraggable, isDropTarget, setDropTarget, isChildOf, isHideInPortrait, setHideInPortrait, getBindablePropertyNames, getBindablePropertyTypes, bindProperty, unbindProperty, getBoundPropertyValue, setBoundPropertyValue, getCloudBoundProperty, setCloudBoundProperty, getCloudDestinationProperty, setCloudDestinationProperty, getComponentState, setComponentState, setHidden, isHidden, setHidden, isHidden, announceForAccessibility, getAccessibilityText, setAccessibilityText, getSemantics, getAccessibilityNode, accessibilityChanged, accessibilityChanged, getTooltip, setTooltip

Constructor details

PhoneNumberField

public PhoneNumberField()
Builds a field defaulting to the country the device reports, falling back to the first entry when the device reports one that is not in the list.

Method details

getCountries

public PhoneNumberField.Country[] getCountries()
The list this field offers, defaulting to every known country.

Returns

the countries offered by the selector

setCountries

public void setCountries(PhoneNumberField.Country[] countries)
Narrows or replaces the list this field offers. An application serving three countries has no reason to show two hundred.

Parameters

countries PhoneNumberField.Country[]
the countries to offer, or null to restore the full list

getCountry

public PhoneNumberField.Country getCountry()
The selected country, never null.

setCountry

public void setCountry(PhoneNumberField.Country c)

Selects a country, which changes the calling code the value is built from without touching the number that was typed.

The country has to be one this field offers. Selecting one that is not leaves the selector showing a country the list it opens does not contain, and the field submitting a calling code the user was never given the chance to choose – a mistake worth hearing about where it is made rather than in a support ticket about numbers from the wrong country.

The object itself is kept rather than replaced by the equal one from the list. Countries are equal by ISO code, so an application that supplies its own entry for a country – a different name, or a calling code it has reason to override – keeps what it passed.

Parameters

c PhoneNumberField.Country
the country; ignored when null

Throws

IllegalArgumentException
when the country is not one this field offers; narrow or widen the list with #setCountries(Country[]) first

getNationalNumber

public String getNationalNumber()
The national part as typed, digits only.

getE164

public String getE164()
The number in E.164 form – “+”, the calling code, then the national number – or null when nothing has been typed.

Returns

the E.164 number, or null when the national part is empty

setE164

public void setE164(String e164)

Sets the field from an E.164 number, selecting the country whose calling code the number starts with and putting the rest in the number field.

Several countries share a calling code (+1 covers the United States, Canada and much of the Caribbean, which the North American area code tells apart and this field does not), and the number alone does not say which. The currently selected country is kept when its code matches, and otherwise the first country listed for that code is selected.

Parameters

e164 String
the number, with or without the leading “+”; null clears the field

isValid

public boolean isValid()
A sanity check on the shape of the number: a national part that is present and short enough to leave the whole number inside E.164’s fifteen digit limit. It is not a check that the number exists, which only the service that sends the message can answer.

Returns

true when the number could be an E.164 number

getNumberField

public TextField getNumberField()
The field holding the national part, exposed for theming and for listening to what is typed.

getCountryButton

public Button getCountryButton()
The button that opens the country list, exposed for theming.

addDataChangedListener

public void addDataChangedListener(DataChangedListener l)
Adds a listener notified as the number is typed.

Parameters

l DataChangedListener
the listener

removeDataChangedListener

public void removeDataChangedListener(DataChangedListener l)
Removes a previously-registered listener.

Parameters

l DataChangedListener
the listener

getAllCountries

public static PhoneNumberField.Country[] getAllCountries()

Every country with a numbering plan of its own, ordered by English name.

A handful of ISO 3166 regions are deliberately absent – see the note on the table itself – because they have no calling code assigned to them. An application that needs one supplies its own list.

findCountry

public static PhoneNumberField.Country findCountry(String isoCode)
Looks a country up by its two letter ISO 3166 code.

Parameters

isoCode String
the code, case insensitive

Returns

the country, or null when the code is not one this list carries