Class CssConvert

java.lang.Object
com.vaadin.swingbridge.surrogates.util.CssConvert

public final class CssConvert extends Object
Stateless conversions between AWT value types (Cursor, Color, Font) and the CSS-string dialect their Vaadin peers speak, plus the inverse parsers that let surrogate getters reconstruct the AWT value by reading the DOM style back (no server-side shadow cache — Vaadin-first per SD_vaadin_first_binding). Pure functions, no state; shared by both modules — :emulators (which stores Swing-side fields per R_swing_is_truth and so only needs the forward AWT→CSS direction) and :surrogates (which round-trips through the DOM and needs the reverse parsers too).

Lives in com.vaadin.swingbridge.surrogates as the lowest module both sides share (:emulators has an api dependency on :surrogates): one copy of each converter, called from both modules.

Border↔CSS conversion is deliberately not here — it carries real internal coupling (private CSS readers, per-UI <style> injection, TitledBorder machinery) and stays in BorderCss.

  • Field Details

    • DEFAULT_FONT

      public static final Font DEFAULT_FONT
      Stand-in for the Look-and-Feel-installed default font that a real Swing component carries from construction (UIManager "TextField.font" and friends). Emulator/surrogate components run no L&F, so nothing installs a per-component font — this fills the same role so getFont() honours Swing's non-null contract and the pervasive GUI-builder idiom comp.setFont(comp.getFont().deriveFont(...)) (which every NetBeans/Matisse initComponents() emits) doesn't NPE. Dialog/plain/12 matches AWT's own logical default and the exact fallbacks fontFromCss(String, String, String, String) already collapses to, so a value read back through getFont() is self-consistent whether it came from this constant or from reconstructed CSS.
  • Method Details

    • columnsToCssWidth

      public static String columnsToCssWidth(int columns)
      Swing's columns hint → a CSS width for the field's host element: "calc(<n>ch + 2em)", or null for n <= 0 ("no hint" — let the peer pick its default).
      new SJTextField().setColumns(3);   // host width: calc(3ch + 2em)
      

      ch is the width of a "0" glyph, close enough to Swing's character-column semantics under R_layouts_close_enough. The 2em term is what makes the hint mean what it says: Vaadin fields are border-box, so the host width has to carry the field's own chrome — input-field padding, borders, and the inner <input>'s own padding — on top of the text. Measured at 22px against a 12px font, i.e. just under 2em; being font-relative it stays proportional as the font grows, and errs slightly wide rather than clipping.

      Not n + "ch". That sizes the host to the text alone, so the chrome eats the whole budget: measured in-browser, a 3-column field ended up with negative room for text and rendered about one digit wide. Nothing server-side can catch that — the CSS is valid and Karibu asserts only the string — so the value this returns is browser-verified, and the Sampler Focus route's 3-digit phone fields are where it shows.

    • toCssCursor

      public static String toCssCursor(Cursor cursor)
      AWT Cursor → CSS cursor keyword for the 14 predefined cursor types. Returns null for Cursor.CUSTOM_CURSOR (or any unknown type) — we cannot rasterize a custom cursor image to a data: URL without a Graphics implementation, so the caller should onUnimplemented and skip writing CSS (letting the style inherit).
    • cursorFromCss

      public static Cursor cursorFromCss(String css)
      CSS cursor keyword → predefined AWT Cursor. Inverse of toCssCursor(Cursor); lets getCursor() reconstruct the Swing value by reading the DOM style directly (no server-side cache). Unknown or non-predefined keywords fall through to Cursor.getDefaultCursor() — the caller gets a non-null Cursor per Swing's convention, which matters for migrated code that chains off the result.
    • parsePxOr1

      public static int parsePxOr1(String css)
      Parse a Vaadin CSS size string (from HasSize#getWidth / HasSize#getHeight) back to an int pixel count. Returns 1 for null, empty, non-pixel units ("%", "em", …), or any unparseable value — not zero: Swing migration code often guards on comp.getWidth() > 0 as a "component is visible" check, and returning 0 for a real-but-CSS-sized component would trip that guard and change behaviour silently.

      Accepts fractional px values ("12.5px") by truncating — AWT dimensions are integer.

    • toCss

      public static String toCss(Color color)
      AWT Color → CSS. rgb() if opaque, rgba() otherwise.
    • colorFromCss

      public static Color colorFromCss(String css)
      Parse a CSS color string written by toCss(Color) back to an AWT Color. Handles rgb(r,g,b) and rgba(r,g,b,a) with the alpha as a decimal fraction. Returns null for null/empty/unparseable inputs — named colors, hex literals, hsl(), and other forms aren't recognised, which is the accepted lossiness of the Vaadin-first stance (SD_vaadin_first_binding): if user code writes a color via getElement().getStyle().set("color", "red") bypassing the mixin, the surrogate-side getter returns null.

      Alpha round-trip: Color(r,g,b,128) writes "rgba(r,g,b,0.502)"; reading back computes Math.round(0.502 * 255) = 128. One-bit slop is possible on extreme values (e.g. 1 → 0.004 → round-trips to 1); generally safe.

    • toHexColor

      public static String toHexColor(Color color)
      AWT Color → #rrggbb hex, the dialect the browser <input type="color"> value property speaks. Alpha is dropped — a color input is opaque-only, so this is deliberately lossy (documented in SD_sjcolorchooser). Use toCss(Color) for the general background/foreground CSS path where alpha matters.
    • colorFromHex

      public static Color colorFromHex(String hex)
      Parse a #rrggbb (or #rgb shorthand) hex color as written by toHexColor(Color) — or as echoed back by the browser <input type="color"> — into an AWT Color. Returns null for null/empty/malformed input (Vaadin-first lossiness per SD_vaadin_first_binding, matching colorFromCss(String)'s null-on-unparseable stance). The result is always opaque (alpha 255) since the color input carries no alpha channel.
    • toCssFontFamily

      public static String toCssFontFamily(Font font)
      AWT logical font families mapped to CSS generics; everything else is quoted with a sans-serif fallback.
    • awtFontFamilyFromCss

      public static String awtFontFamilyFromCss(String css)
      Reverse of toCssFontFamily(Font): map CSS generic font family names back to AWT logical family names. First-token-wins for comma-separated stacks; quoted specifics unquote to their raw name. Returns null for null/empty/unparseable inputs.
    • fontFromCss

      public static Font fontFromCss(String family, String size, String weight, String style)
      Reconstruct an AWT Font by reading the font-family, font-size, font-weight, and font-style slots individually. Returns null when none of the four are set — matches Swing's "no font installed" state.

      Lossy: weights other than bold/normal collapse to plain; font-size in non-px units falls back to 12 (AWT's default size); intermediate CSS (e.g. font-size: calc(1em + 2px)) reads back as 12.