Class PhoneNumberField
- All Implemented Interfaces:
Animation, Editable, StyleListener, Iterable<Component>
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 Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final classA country and its E.164 calling code. -
Field Summary
Fields inherited from class Component
BASELINE, BOTTOM, BRB_CENTER_OFFSET, BRB_CONSTANT_ASCENT, BRB_CONSTANT_DESCENT, BRB_OTHER, CENTER, CROSSHAIR_CURSOR, DEFAULT_CURSOR, DRAG_REGION_IMMEDIATELY_DRAG_X, DRAG_REGION_IMMEDIATELY_DRAG_XY, DRAG_REGION_IMMEDIATELY_DRAG_Y, DRAG_REGION_LIKELY_DRAG_X, DRAG_REGION_LIKELY_DRAG_XY, DRAG_REGION_LIKELY_DRAG_Y, DRAG_REGION_NOT_DRAGGABLE, DRAG_REGION_POSSIBLE_DRAG_X, DRAG_REGION_POSSIBLE_DRAG_XY, DRAG_REGION_POSSIBLE_DRAG_Y, E_RESIZE_CURSOR, HAND_CURSOR, LEFT, MOVE_CURSOR, N_RESIZE_CURSOR, NE_RESIZE_CURSOR, NW_RESIZE_CURSOR, RIGHT, S_RESIZE_CURSOR, SE_RESIZE_CURSOR, SW_RESIZE_CURSOR, TEXT_CURSOR, TOP, W_RESIZE_CURSOR, WAIT_CURSOR -
Constructor Summary
ConstructorsConstructorDescriptionBuilds 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 Summary
Modifier and TypeMethodDescriptionvoidAdds a listener notified as the number is typed.static PhoneNumberField.CountryfindCountry(String isoCode) Looks a country up by its two letter ISO 3166 code.static PhoneNumberField.Country[]Every country with a numbering plan of its own, ordered by English name.The list this field offers, defaulting to every known country.The selected country, never null.The button that opens the country list, exposed for theming.getE164()The number in E.164 form -- "+", the calling code, then the national number -- or null when nothing has been typed.The national part as typed, digits only.The field holding the national part, exposed for theming and for listening to what is typed.booleanisValid()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.voidRemoves a previously-registered listener.voidsetCountries(PhoneNumberField.Country[] countries) Narrows or replaces the list this field offers.voidSelects a country, which changes the calling code the value is built from without touching the number that was typed.voidSets 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.Methods inherited from class Container
add, add, add, add, add, add, addAll, addComponent, addComponent, addComponent, addComponent, animateHierarchy, animateHierarchyAndWait, animateHierarchyFade, animateHierarchyFadeAndWait, animateLayout, animateLayoutAndWait, animateLayoutFade, animateLayoutFadeAndWait, animateUnlayout, animateUnlayoutAndWait, applyRTL, calcPreferredSize, cancelRepaints, clearClientProperties, constrainHeightWhenScrollable, constrainWidthWhenScrollable, contains, createAnimateHierarchy, createAnimateHierarchyFade, createAnimateLayout, createAnimateLayoutFade, createAnimateLayoutFadeAndWait, createAnimateMotion, createAnimateUnlayout, createReplaceTransition, dragInitiated, drop, encloseIn, encloseIn, findDropTargetAt, findFirstFocusable, fireClicked, flushReplace, forceRevalidate, getBottomGap, getChildrenAsList, getClosestComponentTo, getComponentAt, getComponentAt, getComponentCount, getComponentIndex, getGridPosX, getGridPosY, getLayout, getLayoutHeight, getLayoutWidth, getLeadComponent, getLeadParent, getResponderAt, getSafeAreaRoot, getScrollIncrement, getSideGap, getUIManager, initLaf, invalidate, isEnabled, isSafeArea, isSafeAreaRoot, isScrollableX, isScrollableY, isSelectableInteraction, isSurface, iterator, iterator, keyPressed, keyReleased, layoutContainer, morph, morphAndWait, paint, paintComponentBackground, paintGlass, paramString, pointerPressed, refreshTheme, removeAll, removeComponent, replace, replace, replaceAndWait, replaceAndWait, replaceAndWait, revalidate, revalidateLater, revalidateWithAnimationSafety, scrollComponentToVisible, setCellRenderer, setEnabled, setLayout, setLeadComponent, setSafeArea, setSafeAreaRoot, setScrollable, setScrollableX, setScrollableY, setScrollIncrement, setShouldCalcPreferredSize, setShouldLayout, setUIManager, updateTabIndicesMethods inherited from class Component
accessibilityChanged, accessibilityChanged, addContextMenuListener, addDragFinishedListener, addDragOverListener, addDropListener, addFocusListener, addLongPressListener, addMouseWheelListener, addPointerDraggedListener, addPointerPressedListener, addPointerReleasedListener, addPullToRefresh, addScrollListener, addStateChangeListener, addStylusListener, animate, announceForAccessibility, bindProperty, blocksSideSwipe, calcScrollSize, consumesRawTextInput, contains, containsOrOwns, createStyleAnimation, deinitialize, deinitializeCustomStyle, deregisterFromAnimation, dragEnter, dragExit, dragFinished, draggingOver, drawDraggedImage, focusGained, focusLost, getAbsoluteX, getAbsoluteY, getAccessibilityNode, getAccessibilityText, getAllStyles, getAnimationManager, getBaseline, getBaselineResizeBehavior, getBindablePropertyNames, getBindablePropertyTypes, getBorder, getBoundPropertyValue, getBounds, getBounds, getClientProperty, getCloudBoundProperty, getCloudDestinationProperty, getComponentForm, getComponentState, getCursor, getDefaultDragTransparency, getDirtyRegion, getDisabledStyle, getDraggedx, getDraggedy, getDragImage, getDragRegionStatus, getDragSpeed, getDragTransparency, getEditingDelegate, getHeight, getInlineAllStyles, getInlineDisabledStyles, getInlinePressedStyles, getInlineSelectedStyles, getInlineStylesTheme, getInlineUnselectedStyles, getInnerHeight, getInnerPreferredH, getInnerPreferredW, getInnerWidth, getInnerX, getInnerY, getLabelForComponent, getName, getNativeOverlay, getNextFocusDown, getNextFocusLeft, getNextFocusRight, getNextFocusUp, getOuterHeight, getOuterPreferredH, getOuterPreferredW, getOuterWidth, getOuterX, getOuterY, getOwner, getParent, getPreferredH, getPreferredSize, getPreferredSizeStr, getPreferredTabIndex, getPreferredW, getPressedStyle, getPropertyNames, getPropertyTypeNames, getPropertyTypes, getPropertyValue, getSameHeight, getSameWidth, getScrollable, getScrollAnimationSpeed, getScrollDimension, getScrollOpacity, getScrollOpacityChangeSpeed, getScrollX, getScrollY, getSelectCommandText, getSelectedRect, getSelectedStyle, getSemantics, getStyle, getTabIndex, getTensileLength, getTextSelectionSupport, getTooltip, getTopLevelContainer, getUIID, getUnselectedStyle, getVisibleBounds, getVisibleBounds, getWidth, getX, getY, growShrink, handlesInput, hasFixedPreferredSize, hasFocus, hideNativeOverlay, initComponent, initCustomStyle, initDisabledStyle, initPressedStyle, initSelectedStyle, initUnselectedStyle, installDefaultPainter, isAlwaysTensile, isBlockLead, isCellRenderer, isChildOf, isDragActivated, isDragAndDropOperation, isDraggable, isDragRegion, isDropTarget, isEditable, isEditing, isFlatten, isFocusable, isGrabsPointerEvents, isHidden, isHidden, isHideInLandscape, isHideInPortrait, isHScrollThumbGrabbed, isHScrollThumbHover, isIgnorePointerEvents, isInClippingRegion, isInitialized, isOpaque, isOwnedBy, isPinchBlocksDragAndDrop, isRippleEffect, isRTL, isScrollable, isScrollVisible, isSetCursorSupported, isSmoothScrolling, isSnapToGrid, isStickyDrag, isTactileTouch, isTactileTouch, isTensileDragEnabled, isTraversable, isVisible, isVScrollThumbGrabbed, isVScrollThumbHover, keyRepeated, laidOut, longKeyPress, longPointerPress, onScrollX, onScrollY, onSetFocusable, paintBackground, paintBackgrounds, paintBorder, paintBorderBackground, paintComponent, paintComponent, paintIntersectingComponentsAbove, paintLock, paintLockRelease, paintRippleOverlay, paintScrollbars, paintScrollbarX, paintScrollbarY, paintShadows, parsePreferredSize, pinch, pinch, pinchReleased, pointerDragged, pointerDragged, pointerHover, pointerHoverPressed, pointerHoverReleased, pointerPressed, pointerReleased, pointerReleased, putClientProperty, refreshTheme, refreshTheme, registerForAnimation, remove, removeContextMenuListener, removeDragFinishedListener, removeDragOverListener, removeDropListener, removeFocusListener, removeLongPressListener, removeMouseWheelListener, removePointerDraggedListener, removePointerPressedListener, removePointerReleasedListener, removeScrollListener, removeStateChangeListener, removeStylusListener, repaint, repaint, requestFocus, resetFocusable, respondsToPointerEvents, rotation, scrollRectToVisible, scrollRectToVisible, setAccessibilityText, setAlwaysTensile, setBlockLead, setBoundPropertyValue, setCloudBoundProperty, setCloudDestinationProperty, setComponentState, setCursor, setDefaultDragTransparency, setDirtyRegion, setDisabledStyle, setDraggable, setDragTransparency, setDropTarget, setEditingDelegate, setFlatten, setFocus, setFocusable, setGrabsPointerEvents, setHandlesInput, setHeight, setHidden, setHidden, setHideInLandscape, setHideInPortrait, setHorizontalScrollBounds, setIgnorePointerEvents, setInitialized, setInlineAllStyles, setInlineDisabledStyles, setInlinePressedStyles, setInlineSelectedStyles, setInlineStylesTheme, setInlineUnselectedStyles, setIsScrollVisible, setLabelForComponent, setName, setNextFocusDown, setNextFocusLeft, setNextFocusRight, setNextFocusUp, setOpaque, setOwner, setPinchBlocksDragAndDrop, setPreferredH, setPreferredSize, setPreferredSizeStr, setPreferredTabIndex, setPreferredW, setPressedStyle, setPropertyValue, setPullToRefresh, setRippleEffect, setRTL, setSameHeight, setSameSize, setSameWidth, setScrollAnimationSpeed, setScrollOpacityChangeSpeed, setScrollSize, setScrollVisible, setScrollX, setScrollY, setSelectCommandText, setSelectedStyle, setSize, setSmoothScrolling, setSnapToGrid, setTabIndex, setTactileTouch, setTensileDragEnabled, setTensileLength, setTooltip, setTraversable, setUIID, setUIID, setUIIDFinal, setUnselectedStyle, setVerticalScrollBounds, setVisible, setWidth, setX, setY, shouldBlockSideSwipe, shouldBlockSideSwipeLeft, shouldBlockSideSwipeRight, shouldRenderComponentSelection, showNativeOverlay, startEditingAsync, stopEditing, stripMarginAndPadding, styleChanged, toImage, toString, unbindProperty, updateNativeOverlay, visibleBoundsContains
-
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
The list this field offers, defaulting to every known country.
Returns
the countries offered by the selector
-
setCountries
Narrows or replaces the list this field offers. An application serving three countries has no reason to show two hundred.
Parameters
countries: the countries to offer, or null to restore the full list
-
getCountry
The selected country, never null. -
setCountry
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: 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
The national part as typed, digits only. -
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
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: 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
The field holding the national part, exposed for theming and for listening to what is typed. -
getCountryButton
The button that opens the country list, exposed for theming. -
addDataChangedListener
Adds a listener notified as the number is typed.
Parameters
l: the listener
-
removeDataChangedListener
Removes a previously-registered listener.
Parameters
l: the listener
-
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
Looks a country up by its two letter ISO 3166 code.
Parameters
isoCode: the code, case insensitive
Returns
the country, or null when the code is not one this list carries
-