<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 07/08/2025 17:45, Martin Fox wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:9A6D0794-D1A5-45CE-9CF9-838D9A55016E@gmail.com">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <br id="lineBreakAtBeginningOfMessage">
      <div><br>
        <blockquote type="cite">
          <div>On Aug 6, 2025, at 3:54 PM, John Hendrikx
            <a class="moz-txt-link-rfc2396E" href="mailto:john.hendrikx@gmail.com"><john.hendrikx@gmail.com></a> wrote:</div>
          <br class="Apple-interchange-newline">
          <div>
            <meta charset="UTF-8">
            <br
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;">
            <span
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;">On
              06/08/2025 18:06, Martin Fox wrote:</span>
            <blockquote type="cite"
style="font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;">The
              TextField of a ComboBox or Spinner is not just an artifact
              of its skin. They are both explicitly composite controls
              that contains a TextField inside. It’s part of the API.
              And if you were to install some filters on the Scene to
              track Key and InputMethod events you could easily conclude
              that that TextField is the focus owner (it walks like the
              focus owner, it quacks like the focus owner).<br>
            </blockquote>
            <br
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;">
            <span
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;">I
              disagree.  A ComboBox and Spinner are primitives.  Their</span><br
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;">
            <span
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;">implementation
              via replacable Skins may or may not use a TextField,</span><br
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;">
            <span
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;">that's
              completely up to the Skin.</span></div>
        </blockquote>
        <div><br>
        </div>
        As I mentioned in my earlier e-mail (in the paragraph you
        quoted) the TextField is part of the ComboBox and Spinner API.
        Accessing it is the only way to, say, attach a TextFormatter to
        a Spinner. Consult the docs starting at version 2.2.</div>
    </blockquote>
    <p>I took another look here, and printed this field.<br>
      <br>
      - It's a FakeFocusTextField (sigh)<br>
      - It was available immediately even before a Skin was applied<br>
      - It remains available even if another Skin is applied that
      doesn't have a TextField<br>
      <br>
      This really is only another example of lazy design, exposing part
      of the inner workings of a Control to avoid having to duplicate
      some properties that are relevant to Spinners as a primitive.  The
      returned TextField is not mandated to be used by the Skin, and so
      it can just do nothing (ie. if the Skin prefers using a Label). 
      The TextFormatter would be relevant in either case, and should
      have been a top level property, that the Skin may bind to.</p>
    <p>All I'm seeing is a brilliant design idea (skinnable controls,
      with separated behaviors) executed poorly:</p>
    <p>- Behavior and Skins referring to each other<br>
      - Skins given too much access to Controls (write access to any
      property should not be allowed, nor should Skins be allowed to
      install event handlers on their host Control)<br>
      - Behaviors installing Event Handlers directly mixing with user
      handlers<br>
      - Controls exposing sub controls that it can't guarantee will be
      there or used, per how Skins work<br>
      - Events not being targetted at the Control black box<br>
      - Internal Skin level Events leaking to the outside world
      (completely unnecessarily as this can be 100% avoided already now)<br>
      - Skins not being isolated properly so replacing Skins can leave
      old listeners behind (it requires co-operation of the Skin, while
      it should be automatic)<br>
      - Behavior's handling navigation events directly instead of
      letting them bubble up often blocking users from handling them
      first<br>
      - ... and now another: failure to hoist up relevant properties to
      the main Control (or make them styleable and part of the Skin
      provided properties)</p>
    <blockquote type="cite"
      cite="mid:9A6D0794-D1A5-45CE-9CF9-838D9A55016E@gmail.com">
      <div>The proposal (lifted from WPF) is to provide a mechanism
        which would allow a Control to replace an event’s original
        target with itself. This is a low-cost way of making the control
        appear to be a black box at the event level. It would certainly
        have a lower cost than, say, trying to hide skin nodes from the
        rest of the scene graph. I’m not aware of any toolkit that even
        attempts that.</div>
    </blockquote>
    Skins by their definition have free reign what nodes they create. 
    It's not hiding anything when you simply can't, nor should rely on
    anything being there specifically.  It therefore makes sense to
    disallow access to these nodes programmatically for the user. These
    extra nodes (if they exist) are only targettable by CSS, which is
    fine in my book as CSS can set a Skin, or know what Skins are
    present by default for a default stylesheet.  <br>
    <br>
    I'm not saying this can be changed still, I'm saying what it should
    have been had the idea of Skins not been subverted into its current
    state.  I would like to prevent adding any more leaks, and plugging
    leaks that we can.<br>
    <br>
    Adding an extra field to events to support the internal event
    dispatching system (preferably not public API) is fine with me.<br>
    <blockquote type="cite"
      cite="mid:9A6D0794-D1A5-45CE-9CF9-838D9A55016E@gmail.com">
      <div><br>
      </div>
      <div>
        <blockquote type="cite">
          <div><span
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;">-
              Skins re-use listener and event handler endpoints on the
              Control,</span><br
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;">
            <span
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;">leaving
              users baffled by events sometimes being consumed before
              they see</span><br
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;">
            <span
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;">them
              (if they added their handler late) or after they see them
              (if they</span><br
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;">
            <span
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;">were
              the first to add their handler, or if the Skin was
              replaced causing</span><br
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;">
            <span
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;">a
              re-ordering -- something very interesting to deal with);
              for listeners</span><br
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;">
            <span
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;">this
              is relatively safe, as they don't have a consumption
              mechanism, but</span><br
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;">
            <span
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;">not
              for events --  another mistake; skin event handlers should
              have been</span><br
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;">
            <span
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;">part
              of a separate list so there can never be any intermixing
              of user</span><br
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;">
            <span
style="caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;">and
              skin event handlers</span></div>
        </blockquote>
        <br>
      </div>
      This is a known pain point for developers that can be fixed
      without re-writing the underpinnings of JavaFX (in other words,
      with a reasonable cost/benefit ratio). I’m not sure why it hasn’t
      been done already.<br>
    </blockquote>
    I have no idea either, it's a no-brainer.<br>
    <br>
    --John<br>
    <blockquote type="cite"
      cite="mid:9A6D0794-D1A5-45CE-9CF9-838D9A55016E@gmail.com">
      <div>
        <div><br>
        </div>
        <div>Martin</div>
      </div>
    </blockquote>
  </body>
</html>