Saltar al contenido
CrossFly es 100% open sourceSíguenos en GitHub
CrossFlyCrossFly
Empezar
Todos los ejemplos
RecetasFormulariosEntrada84 líneas · 1 archivos

A form that fights back

setMode does most of the work: it picks the keyboard, the mask and the validation together. A regex on the way out only tells the user they already got it wrong.

Qué muestra esto

A form that prevents mistakes instead of complaining about them afterwards.

Ejecutarlo en tu máquina

Cada ejemplo es una Window normal, así que el lanzador solo necesita su nombre.

gradlew lwjgl3:run --args="classname dev.cf.recipe.R10Form"
Editarlo

Java se compila antes de ejecutarse, así que el navegador no puede reconstruir una edición por su cuenta: el código que ves aquí se convirtió en JavaScript con TeaVM antes de publicarse. Copia el archivo a un proyecto y funciona sin cambios en las cuatro plataformas; el comando de arriba es toda la preparación.

Ejecutándose aquíCrossFly 0.1.32
Iniciando la aplicación…

Compilado a JavaScript por TeaVM: es el mismo código, no un vídeo de él. · Todos los ejemplos

Qué usa

Tipos del framework que toca este ejemplo. Los enlazados tienen página de referencia.

ButtonComponentHintLabelScreenTextFieldTextFieldStyleWidgets

El código

Completo, sin recortes. Es el archivo, no un fragmento.

Crudo
dev/cf/recipe/R10Form.java
package dev.cf.recipe;

import dev.cf.Tones;

import dev.crossfly.ui.*;
import dev.crossfly.ui.color.*;
import dev.crossfly.ui.graphics.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.style.*;

import static dev.crossfly.ui.Widgets.*;

/**
 * A form that prevents mistakes instead of complaining about them afterwards.
 */
public class R10Form extends Recipe
{
   private TextField amount, when, pin;
   private Label problem;

   public String title()
   {
      return "A form that fights back";
   }

   public String note()
   {
      return "setMode does most of the work: it picks the keyboard, the mask and the validation"
         + " together. A regex on the way out only tells the user they already got it wrong.";
   }

   public void build(Component body) throws Exception
   {
      // CURRENCY masks as you type and gives a numeric keyboard on a phone. Two decimals is the
      // mask's business, not the screen's — no parsing here, no "please use a dot".
      amount = field(body, "Amount", EditMode.CURRENCY);

      // DATE opens the date picker rather than a text keyboard, so an impossible date cannot be
      // typed at all. Same for TIME.
      when = field(body, "Date", EditMode.DATE);

      pin = field(body, "PIN", EditMode.PASSWORD);
      // maxLength lives on the STYLE, not on the field — along with the mask, the valid characters
      // and the keyboard. Worth knowing before you write your own length check in a key handler.
      TextFieldStyle st = pin.getStyle();
      st.maxLength(6);

      // The message is the one thing on this screen that means something went wrong, so it is the
      // one thing wearing the error tone. In secondary grey it read as another caption.
      problem = label("", 1f, true, Tones.danger(), Position.START);
      problem.setVisible(false);
      body.add(LAY_AUTO, outgap(problem, 0, .4f, 0, .4f));

      Button ok = Tones.action("Submit");
      ok.testTag("form.submit");
      ok.onAction(c -> submit());
      body.add(LAY_AUTO, ok);
   }

   private TextField field(Component body, String caption, EditMode mode) throws Exception
   {
      TextField f = new TextField();
      f.caption(caption);
      f.setMode(mode);
      f.testTag("form." + caption.toLowerCase());
      body.add(LAY_AUTO, outgap(f, 0, 0, 0, .7f));
      return f;
   }

   /** Says WHICH field and WHY. "Please complete all fields" is what a form says when nobody owns the rule. */
   private void submit()
   {
      String p = amount.getText().isEmpty() ? "How much? The amount is still empty."
         : when.getText().isEmpty() ? "Pick a date — tap the field and the picker opens."
            : pin.getText().length() < 4 ? "The PIN is at least four digits." : null;
      problem.setText(p == null ? "" : p);
      problem.setVisible(p != null);
      problem.setValidLayout(false);
      if (p == null)
         Hint.show("Submitted", 2000);
      Screen.repaint();
   }
}
Para una IA

Versiones de esta página legibles por máquina, para que un modelo lea el estante en vez de adivinar la API.

Este ejemplo, en JSONEste ejemplo, en Markdown
AnteriorMaking a screen testableSiguienteTelling the user something