Skip to content
CrossFly is 100% open sourceFollow us on GitHub
CrossFlyCrossFly
Get started

This page was machine-translated from Portuguese and may contain errors. The Portuguese version is canonical.

How to apply a CPF, ZIP code, or date mask

Purpose. Automatically format typing with separators (dots, dashes, slashes) showing 123.456.789-00 while the user types only the digits, and later retrieve the clean value (12345678900).

APIs used

  • campo.<TextFieldStyle>getStyle().mask("999.999.999-99".toCharArray()) — defines the mask pattern. 9 = digit position; any other character is a literal inserted automatically (., -, /).
  • .mode(EditMode.NUMERIC, true) — turns on numeric mode AND maskedEdit (second parameter true). Without maskedEdit the mask is not applied. Order matters: call mask(...) and mode(...) together.
  • TextField.getText() — returns the text WITH the mask ("123.456.789-00"), ideal for displaying/saving formatted.
  • TextField.getTextWithoutMask() — returns only the digits of the 9 positions ("12345678900"), ideal for validating and sending to the backend.

For dates, prefer setMode(EditMode.DATE, true): it automatically derives the mask from the locale (LocaleFormats.dateSeparator and LocaleFormats.dateFormat, e.g., dd/MM/yyyy or yyyy-MM-dd) and also opens the DatePicker. See the Date and time recipe.

Mind the order in mode(EditMode.NUMERIC, true): the NUMERIC/NORMAL mode only recalculates maxLength from the mask if the mask is already defined. Set mask(...) before or in the same fluent chain.

Complete example (copy, paste, and run)

package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.style.*;   // TextFieldStyle (config on the style)

/** Runnable main screen. Point the launcher (classname) and run: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      // CPF: 123.456.789-00
      TextField cpf = new TextField("");
      cpf.caption("CPF");
      cpf.<TextFieldStyle>getStyle()
         .mask("999.999.999-99".toCharArray())
         .mode(EditMode.NUMERIC, true);   // NUMERIC + maskedEdit

      // CEP: 12345-678
      TextField cep = new TextField("");
      cep.caption("CEP");
      cep.<TextFieldStyle>getStyle()
         .mask("99999-999".toCharArray())
         .mode(EditMode.NUMERIC, true);

      Label resultado = new Label("");

      Button enviar = new Button("Enviar");
      enviar.onAction(o ->
      {
         String cpfFormatado = cpf.getText();            // "123.456.789-00"
         String cpfLimpo     = cpf.getTextWithoutMask(); // "12345678900"
         if (cpfLimpo.length() != 11)
         {
            Hint.show("CPF deve ter 11 dígitos", 2000);
            return;
         }
         resultado.setText(cpfFormatado + " · CEP: " + cep.getText());
      });

      add(LAY_FILL, cpf);
      add(LAY_FILL, cep);
      add(LAY_AUTO, enviar);
      add(LAY_FILL, resultado);
   }
}

The snippet below shows only the core. To run it, place it in the MainWindow skeleton above.

Minimal snippet

import dev.crossfly.ui.*;
import dev.crossfly.ui.style.*;
import static dev.crossfly.ui.UIConstants.EditMode;

// CPF: 123.456.789-00
TextField cpf = new TextField("");
cpf.caption("CPF");
cpf.<TextFieldStyle>getStyle()
   .mask("999.999.999-99".toCharArray())
   .mode(EditMode.NUMERIC, true);   // NUMERIC + maskedEdit

// CEP: 12345-678
TextField cep = new TextField("");
cep.caption("CEP");
cep.<TextFieldStyle>getStyle()
   .mask("99999-999".toCharArray())
   .mode(EditMode.NUMERIC, true);

Button enviar = new Button("Enviar");
enviar.onAction(o ->
{
   String cpfFormatado = cpf.getText();            // "123.456.789-00"
   String cpfLimpo     = cpf.getTextWithoutMask(); // "12345678900"
   // validates cpfLimpo.length() == 11 and submits
});

Dig deeper

Was this page helpful?