<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:"Iosevka Fixed SS16";
        panose-1:2 0 5 9 3 0 0 0 0 4;}
@font-face
        {font-family:"Times New Roman \(Body CS\)";
        panose-1:2 11 6 4 2 2 2 2 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        font-size:10.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
span.EmailStyle19
        {mso-style-type:personal-reply;
        font-family:"Iosevka Fixed SS16";
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;
        mso-ligatures:none;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style>
</head>
<body lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">Michael:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">Thank you for a very thoughtful analysis!  These are very good questions; allow me to clarify.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:11.0pt">1. It seems that the behavior implementation is still hard-coded into<br>
the skin implementation. For example, TextFieldSkin uses<br>
TextFieldBehavior; it doesn't seem like I can have a TextFieldSkin<br>
that uses my custom behavior. Do you plan on changing that?</span><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">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.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">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).<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">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).<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:11.0pt">2. The InputMap can have a lot of mappings that are set on each<br>
individual control. However, in almost all cases, the input mappings<br>
are semantically equivalent for all instances of a control. Wouldn't<br>
it make sense to associate input mappings with the control class,<br>
instead of the control instance? Aside from more closely conveying the<br>
semantics of a "default mapping", this should also cut down on the<br>
number of object instances we need to keep around. Of course, it<br>
should still be possible to override a default mapping with a<br>
per-instance mapping.</span><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">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!<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:11.0pt">3. Why are FunctionTags defined on the control class, yet they don't<br>
seem to match the functionality offered by the control class? For<br>
example, there's TextInputControl.DELETE_NEXT_WORD, but there's no<br>
corresponding functionality in TextInputControl. The functionality is<br>
actually implemented in TextInputControlBehavior. But if the<br>
implementation is only available in this particular behavior, why is<br>
the FunctionTag defined on the control class?</span><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">The function tags belong to the control class so that the user can redefine them.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">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.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:11.0pt">4. I'm missing a clear delineation between controls and their<br>
behaviors. For example, there's TextInputControl.selectNextWord(), but<br>
no TextInputControl.deleteNextWord(). The latter is implemented in<br>
TextInputControlBehavior. Why is selectNextWord() implemented in the<br>
control, but deleteNextWord() in the behavior? This is just one<br>
example of lots of peculiarities.</span><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">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().<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">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.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in"><span style="font-size:11.0pt">5. More generally, we should start by clearly defining concepts. Up<br>
until now, behaviors were just an implementation detail, so this<br>
wasn't necessary. But what is a behavior? What is the relationship<br>
between a control, its skin and behavior? How would a control author<br>
decide what needs to be put into the control class, and what needs to<br>
be put into the behavior class (cf. selectNextWord/deleteNextWord)?</span><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">Good point.  Perhaps the best place to explain this is in FunctionTag Javadoc?<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">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.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">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.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">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.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">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.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">Thank you!<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">-andy<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<div id="mail-editor-reference-message-container">
<div>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal" style="margin-bottom:12.0pt"><b><span style="font-size:12.0pt;color:black">From:
</span></b><span style="font-size:12.0pt;color:black">Michael Strauß <michaelstrau2@gmail.com><br>
<b>Date: </b>Friday, October 6, 2023 at 07:13<br>
<b>To: </b>Andy Goryachev <andy.goryachev@oracle.com><br>
<b>Cc: </b>openjfx-dev@openjdk.org <openjfx-dev@openjdk.org><br>
<b>Subject: </b>[External] : Re: [Request for Comments] Behavior / InputMap<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">Hi Andy,<br>
<br>
I think the opaqueness of JavaFX controls is one of the greatest<br>
shortcomings of the framework, so I welcome an enhancement.<br>
<br>
Some thoughts:<br>
<br>
1. It seems that the behavior implementation is still hard-coded into<br>
the skin implementation. For example, TextFieldSkin uses<br>
TextFieldBehavior; it doesn't seem like I can have a TextFieldSkin<br>
that uses my custom behavior. Do you plan on changing that?<br>
<br>
2. The InputMap can have a lot of mappings that are set on each<br>
individual control. However, in almost all cases, the input mappings<br>
are semantically equivalent for all instances of a control. Wouldn't<br>
it make sense to associate input mappings with the control class,<br>
instead of the control instance? Aside from more closely conveying the<br>
semantics of a "default mapping", this should also cut down on the<br>
number of object instances we need to keep around. Of course, it<br>
should still be possible to override a default mapping with a<br>
per-instance mapping.<br>
<br>
3. Why are FunctionTags defined on the control class, yet they don't<br>
seem to match the functionality offered by the control class? For<br>
example, there's TextInputControl.DELETE_NEXT_WORD, but there's no<br>
corresponding functionality in TextInputControl. The functionality is<br>
actually implemented in TextInputControlBehavior. But if the<br>
implementation is only available in this particular behavior, why is<br>
the FunctionTag defined on the control class?<br>
<br>
4. I'm missing a clear delineation between controls and their<br>
behaviors. For example, there's TextInputControl.selectNextWord(), but<br>
no TextInputControl.deleteNextWord(). The latter is implemented in<br>
TextInputControlBehavior. Why is selectNextWord() implemented in the<br>
control, but deleteNextWord() in the behavior? This is just one<br>
example of lots of peculiarities.<br>
<br>
5. More generally, we should start by clearly defining concepts. Up<br>
until now, behaviors were just an implementation detail, so this<br>
wasn't necessary. But what is a behavior? What is the relationship<br>
between a control, its skin and behavior? How would a control author<br>
decide what needs to be put into the control class, and what needs to<br>
be put into the behavior class (cf. selectNextWord/deleteNextWord)?<br>
<br>
<br>
<br>
On Sat, Sep 30, 2023 at 1:18 AM Andy Goryachev<br>
<andy.goryachev@oracle.com> wrote:<br>
><br>
> Dear fellow JavaFX developers:<br>
><br>
><br>
><br>
> 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.<br>
><br>
><br>
><br>
> 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.<br>
><br>
><br>
><br>
> Please find the actual proposal here<br>
><br>
> <a href="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$</a>
<br>
><br>
><br>
><br>
> We are very much interested in your feedback.  Thank you in advance.<br>
><br>
><br>
><br>
> -andy<br>
><br>
><o:p></o:p></span></p>
</div>
</div>
</div>
</div>
</body>
</html>