[External] : Re: [Request for Comments] Behavior / InputMap
Andy Goryachev
andy.goryachev at oracle.com
Fri Oct 6 17:16:30 UTC 2023
Michael:
Thank you for a very thoughtful analysis! These are very good questions; allow me to clarify.
1. It seems that the behavior implementation is still hard-coded into
the skin implementation. For example, TextFieldSkin uses
TextFieldBehavior; it doesn't seem like I can have a TextFieldSkin
that uses my custom behavior. Do you plan on changing that?
There are many facets to this question. Yes, in my opinion, we should make all the behaviors public similarly to Swing, though it does represent a substantial amount of work. I’d say it is still a possibility, albeit a distant one.
The next best thing is this proposal, which makes it possible to redefine the behavior by re-registering some if not all of the functions declared by the control. Another possibility would be to create a new skin with a custom behavior (though it might be a bit too much for an app developer).
One good thing about this proposal is that it should offer immediate benefits to the application developers in many cases by giving the ability to redefine a small subset of control’s functionality without the need to go deep into implementation (and without making the behavior public).
2. The InputMap can have a lot of mappings that are set on each
individual control. However, in almost all cases, the input mappings
are semantically equivalent for all instances of a control. Wouldn't
it make sense to associate input mappings with the control class,
instead of the control instance? Aside from more closely conveying the
semantics of a "default mapping", this should also cut down on the
number of object instances we need to keep around. Of course, it
should still be possible to override a default mapping with a
per-instance mapping.
This is an interesting idea, we might explore it further – there is nothing in the proposed APIs that preclude us from doing this optimization, even though the actual savings in terms of memory may not be that noticeable: unlike Node, a typical number of Controls in the scene graphs is not that great. But still, worth exploring. Thank you!
3. Why are FunctionTags defined on the control class, yet they don't
seem to match the functionality offered by the control class? For
example, there's TextInputControl.DELETE_NEXT_WORD, but there's no
corresponding functionality in TextInputControl. The functionality is
actually implemented in TextInputControlBehavior. But if the
implementation is only available in this particular behavior, why is
the FunctionTag defined on the control class?
The function tags belong to the control class so that the user can redefine them.
And thank you for pointing out the situation with DELETE_NEXT_WORD. You are right - the actual control class should declare a public method for each tag, so the functionality is available programmatically at the control level. It’s not currently done in this PR in order to minimize the amount of changes, and I expect we’ll do it in a separate enhancement.
4. I'm missing a clear delineation between controls and their
behaviors. For example, there's TextInputControl.selectNextWord(), but
no TextInputControl.deleteNextWord(). The latter is implemented in
TextInputControlBehavior. Why is selectNextWord() implemented in the
control, but deleteNextWord() in the behavior? This is just one
example of lots of peculiarities.
I tried to address this in the proposal, perhaps I did not emphasized it strongly enough. As with your previous comment, a concrete control class should declare a public method for each function tag, which simply executes that function tag. In essence, there should be 1:1:1 correspondence between function tags, public method in the control class, and a public method in the corresponding behavior. The latter is not available directly because right now the actual behavior is not public, but it is available programmatically via getDefaultFunction().
I’d expect there will be subsequent enhancements to add these methods to each control, once we all agree with the proposed design and finalize the APIs.
5. More generally, we should start by clearly defining concepts. Up
until now, behaviors were just an implementation detail, so this
wasn't necessary. But what is a behavior? What is the relationship
between a control, its skin and behavior? How would a control author
decide what needs to be put into the control class, and what needs to
be put into the behavior class (cf. selectNextWord/deleteNextWord)?
Good point. Perhaps the best place to explain this is in FunctionTag Javadoc?
Any function that the skin, or the application developer, or the end user might want to redefine, or set a key binding for, or unbind – should have a corresponding function tag. I’d expect there should be a public method in the control that executes the tag, but it is not a strict requirement.
The relationship between the skin and control is a more subtle one. For example, selectNextWord may not need a skin (it can operate directly on the data model, using a BreakIterator), but TextArea.LINE_END needs the skin to determine where the text layout wrapped the line. A null skin is also technically possible (though it makes no sense). My point is that, given this dependency on the skin, the behavior is typically instantiated by the skin, but it does not have to be. Nothing prevents us from initializing the behavior in the control, and designing this behavior to get the skin when needed. However, this design might have a price of adding some public APIs to the concrete skins.
This proposal does not require making behaviors public, does not mandate additional public APIs in skins, so we are free to change it later if deemed necessary.
Hope this discussion spurs more discussion. My goal is to make FX more extensible and easier to use, and your feedback and comments are very important.
Thank you!
-andy
From: Michael Strauß <michaelstrau2 at gmail.com>
Date: Friday, October 6, 2023 at 07:13
To: Andy Goryachev <andy.goryachev at oracle.com>
Cc: openjfx-dev at openjdk.org <openjfx-dev at openjdk.org>
Subject: [External] : Re: [Request for Comments] Behavior / InputMap
Hi Andy,
I think the opaqueness of JavaFX controls is one of the greatest
shortcomings of the framework, so I welcome an enhancement.
Some thoughts:
1. It seems that the behavior implementation is still hard-coded into
the skin implementation. For example, TextFieldSkin uses
TextFieldBehavior; it doesn't seem like I can have a TextFieldSkin
that uses my custom behavior. Do you plan on changing that?
2. The InputMap can have a lot of mappings that are set on each
individual control. However, in almost all cases, the input mappings
are semantically equivalent for all instances of a control. Wouldn't
it make sense to associate input mappings with the control class,
instead of the control instance? Aside from more closely conveying the
semantics of a "default mapping", this should also cut down on the
number of object instances we need to keep around. Of course, it
should still be possible to override a default mapping with a
per-instance mapping.
3. Why are FunctionTags defined on the control class, yet they don't
seem to match the functionality offered by the control class? For
example, there's TextInputControl.DELETE_NEXT_WORD, but there's no
corresponding functionality in TextInputControl. The functionality is
actually implemented in TextInputControlBehavior. But if the
implementation is only available in this particular behavior, why is
the FunctionTag defined on the control class?
4. I'm missing a clear delineation between controls and their
behaviors. For example, there's TextInputControl.selectNextWord(), but
no TextInputControl.deleteNextWord(). The latter is implemented in
TextInputControlBehavior. Why is selectNextWord() implemented in the
control, but deleteNextWord() in the behavior? This is just one
example of lots of peculiarities.
5. More generally, we should start by clearly defining concepts. Up
until now, behaviors were just an implementation detail, so this
wasn't necessary. But what is a behavior? What is the relationship
between a control, its skin and behavior? How would a control author
decide what needs to be put into the control class, and what needs to
be put into the behavior class (cf. selectNextWord/deleteNextWord)?
On Sat, Sep 30, 2023 at 1:18 AM Andy Goryachev
<andy.goryachev at oracle.com> wrote:
>
> Dear fellow JavaFX developers:
>
>
>
> For some time now, we’ve been working to identify missing features in JavaFX that hinder application development. We’ve been working on adding some of the missing features (for which we’ll have a separate announcement), but I feel that engaging wider community is a rather important part of the process.
>
>
>
> I would like to share with you one such missing feature - ability to extend behavior of the existing components (and make the task of creating new components easier) by adding a public InputMap and BehaviorBase.
>
>
>
> Please find the actual proposal here
>
> https://urldefense.com/v3/__https://gist.github.com/andy-goryachev-oracle/294d8e4b3094fe16f8d55f6dd8b21c09__;!!ACWV5N9M2RV99hQ!LvBDJOf2E21l1kuyLzVGMuLC-fz3U_lgl_5RBWp9nwRKm2IsRgmKcm7bMHRKSh7bmVIfkHiUAE5F1E7tZIeGKujFuEb7$<https://urldefense.com/v3/__https:/gist.github.com/andy-goryachev-oracle/294d8e4b3094fe16f8d55f6dd8b21c09__;!!ACWV5N9M2RV99hQ!LvBDJOf2E21l1kuyLzVGMuLC-fz3U_lgl_5RBWp9nwRKm2IsRgmKcm7bMHRKSh7bmVIfkHiUAE5F1E7tZIeGKujFuEb7$>
>
>
>
> We are very much interested in your feedback. Thank you in advance.
>
>
>
> -andy
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/openjfx-dev/attachments/20231006/ca9e1589/attachment-0001.htm>
More information about the openjfx-dev
mailing list