On 07/08/2025 17:45, Martin Fox wrote:
>
>
>> On Aug 6, 2025, at 3:54 PM, John Hendrikx <john.hendr...@gmail.com>
>> wrote:
>>
>>
>> On 06/08/2025 18:06, Martin Fox wrote:
>>> 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).
>>
>> I disagree.  A ComboBox and Spinner are primitives.  Their
>> implementation via replacable Skins may or may not use a TextField,
>> that's completely up to the Skin.
>
> 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.

I took another look here, and printed this field.

- It's a FakeFocusTextField (sigh)
- It was available immediately even before a Skin was applied
- It remains available even if another Skin is applied that doesn't have
a TextField

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.

All I'm seeing is a brilliant design idea (skinnable controls, with
separated behaviors) executed poorly:

- Behavior and Skins referring to each other
- 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)
- Behaviors installing Event Handlers directly mixing with user handlers
- Controls exposing sub controls that it can't guarantee will be there
or used, per how Skins work
- Events not being targetted at the Control black box
- Internal Skin level Events leaking to the outside world (completely
unnecessarily as this can be 100% avoided already now)
- 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)
- Behavior's handling navigation events directly instead of letting them
bubble up often blocking users from handling them first
- ... and now another: failure to hoist up relevant properties to the
main Control (or make them styleable and part of the Skin provided
properties)

> 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.
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. 

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.

Adding an extra field to events to support the internal event
dispatching system (preferably not public API) is fine with me.
>
>> - Skins re-use listener and event handler endpoints on the Control,
>> leaving users baffled by events sometimes being consumed before they see
>> them (if they added their handler late) or after they see them (if they
>> were the first to add their handler, or if the Skin was replaced causing
>> a re-ordering -- something very interesting to deal with); for listeners
>> this is relatively safe, as they don't have a consumption mechanism, but
>> not for events --  another mistake; skin event handlers should have been
>> part of a separate list so there can never be any intermixing of user
>> and skin event handlers
>
> 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.
I have no idea either, it's a no-brainer.

--John
>
> Martin

Reply via email to