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 validate a text field

Purpose. Ensure the user can only type valid characters, limit the number of characters, and get the value without a mask at submission time. In CrossFly, input validation is declarative (done in the field’s style), and business validation is done on submit.

APIs used

  • campo.<TextFieldStyle>getStyle().validChars("0123456789") — filters the accepted characters. null (default) accepts everything. The comparison is done in UPPERCASE: internally isCharValid(c) does validChars.indexOf(Character.toUpperCase(c)), so provide the letters in uppercase even if the field accepts lowercase.
  • campo.<TextFieldStyle>getStyle().maxLength(11) — limits the total number of characters (0 = unlimited). Applies to typing and to pasting (clipboardPaste).
  • campo.<TextFieldStyle>getStyle().capitalise(Capitalise.UPPER) — forces UPPERCASE/lowercase (UPPER, LOWER, NORMAL).
  • TextField.getText() — text as displayed (with mask, if any).
  • TextField.getTextWithoutMask() — only the digits/raw content (e.g., "12345678900" instead of "123.456.789-00"). Use this on submit.
  • TextInput.mapKeys(from, to) — remaps keys (e.g., replace a comma with a dot). from and to must have the same length.

There is no per-key callback in CrossFly. There is no onTextChanged — you read getText()/getTextWithoutMask() at submission time (or inside the button’s onAction).

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());

      TextField cpf = new TextField("");
      cpf.caption("CPF");
      cpf.<TextFieldStyle>getStyle()
         .validChars("0123456789")   // digits only
         .maxLength(11);             // 11 digits

      TextField apelido = new TextField("");
      apelido.caption("Apelido");
      apelido.<TextFieldStyle>getStyle()
         .capitalise(Capitalise.LOWER)
         .maxLength(20);

      Label resultado = new Label("");

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

      add(LAY_FILL, cpf);
      add(LAY_FILL, apelido);
      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.Capitalise;

TextField cpf = new TextField("");
cpf.caption("CPF");
cpf.<TextFieldStyle>getStyle()
   .validChars("0123456789")   // digits only
   .maxLength(11);             // 11 digits

TextField apelido = new TextField("");
apelido.caption("Apelido");
apelido.<TextFieldStyle>getStyle()
   .capitalise(Capitalise.LOWER)
   .maxLength(20);

Button enviar = new Button("Enviar");
enviar.onAction(origin ->
{
   String cpfLimpo = cpf.getTextWithoutMask();   // "12345678900"
   if (cpfLimpo.length() != 11)
   {
      new Alert("Erro", "CPF deve ter 11 dígitos").show();
      return;
   }
   // ... proceeds with submit
});

Dig deeper

Was this page helpful?