Class PasswordField


public class PasswordField extends TextField
TextField that renders every character as a mask dot, with an optional reveal toggle. While masked, copy/cut are blocked (the clipboard never sees the secret); paste and all editing behave like a TextField.

The dot is drawn, not typeset; see DOT_DIAMETER. Everything else (geometry, padding, the animated border) is inherited from TextField: this class declares no extent of its own beyond the dot's two ratios.

The content is never shaped. shapeDisplay(java.lang.String, limn.graphics.Font) builds the masked line from ShapedText.uniform(java.lang.String, limn.graphics.Font, float, limn.graphics.TextMetrics, long), which is one multiplication and no glyphs, so the secret never reaches a shaper nor the memo a shaper keeps — and the caret, the click mapping, the selection band and the painted dots then all come out of that one piece of arithmetic instead of two that have to be kept in agreement.

  • Constructor Details

    • PasswordField

      public PasswordField()
  • Method Details

    • isRevealed

      public boolean isRevealed()
      Whether the characters are shown instead of the mask.
    • setRevealed

      public PasswordField setRevealed(boolean newRevealed)
      Shows/hides the real text (the optional "reveal" toggle).
    • shapeDisplay

      protected ShapedText shapeDisplay(String text, Font font)
      The masked line: one dot cell per grapheme cluster, built by arithmetic and not by a shaper.

      ShapedText.uniform(java.lang.String, limn.graphics.Font, float, limn.graphics.TextMetrics, long) is what makes the whole class two overrides instead of a pair of parallel measurements. It gives a line whose index space is the model's, so the caret, the selection range and a click need no translation from source offsets to mask offsets — the count-preserving substitution the old mask string had to guarantee is not a thing that can go wrong any more, because there is no second string. And the content does not reach shape, which is the reason this override exists: a shaper resolves faces, memoizes what it was asked, and would be a place a secret comes to rest.

      Cells are grapheme clusters, so one dot stands for one user-perceived character and the caret can never land at a fractional dot: an astral character is one dot, not two, which also keeps the mask from leaking that a character was astral.

      Overrides:
      shapeDisplay in class TextField
      Parameters:
      text - the model's text, which is the index space of the result
      font - the font the line is drawn in
      Returns:
      the shaped display line; never null
    • paintDisplayText

      protected void paintDisplayText(Canvas canvas, ShapedText display, float x, float baseline, TextMetrics metrics, SizeTokens t, Color ink)
      Paints the mask as circles on the ink box's centre line.

      The centre is baseline - ascent + height/2, the middle of the same band the selection fill and the caret span, so the dots stay centred against any face the field's own text would use, at any step, with no per-font vertical fudge. (A dot has no baseline of its own to sit on: this is why the vertical anchor is the band and not the baseline.)

      Overrides:
      paintDisplayText in class TextField
      Parameters:
      canvas - where to draw
      display - the shaped display line, as TextField.shapeDisplay(java.lang.String, limn.graphics.Font) produced it
      x - left edge of the line, in this widget's coordinates
      baseline - the text baseline, in this widget's coordinates
      metrics - the line's vertical band
      t - the size row resolved for this pass
      ink - the colour to draw in
    • allowClipboardCopy

      protected boolean allowClipboardCopy()
      Description copied from class: TextField
      Whether copy/cut may export the content (password fields say no).
      Overrides:
      allowClipboardCopy in class TextField
    • allowsWordJumps

      protected boolean allowsWordJumps()
      While masked, word-wise caret jumps and deletes would let an observer count the words and their lengths inside the secret; modifier+arrows degrade to per-character moves until revealed.
      Overrides:
      allowsWordJumps in class TextField
    • acceptsTextInput

      protected boolean acceptsTextInput()
      Secure text entry keeps the platform IME off (the convention of NSSecureTextField/ES_PASSWORD): composition would echo the secret in cleartext between the mask characters, surface it in the OS candidate window, and feed it to the IME's learning dictionary. The scene also drops preedit events for widgets that refuse text input, so no composition can reach this field even mid-teardown. Direct key/char input (including paste) is unaffected.
      Overrides:
      acceptsTextInput in class TextField