<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=Windows-1252">
<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:"Yu Gothic";
panose-1:2 11 4 0 0 0 0 0 0 0;}
@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;}
@font-face
{font-family:"\@Yu Gothic";
panose-1:2 11 4 0 0 0 0 0 0 0;}
@font-face
{font-family:"Iosevka Fixed SS16 ";
panose-1:2 0 5 9 3 0 0 0 0 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.EmailStyle20
{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";color:#212121">Dear John:</span><span style="color:#212121"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121"> </span><span style="color:#212121"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121">Based on what I understand about your proposal now, I think it’s a variant of the same thing, not fully developed and in some places based on the incorrect assumptions
(S/B separation, stateless B). But you know I am biased :-)</span><span style="color:#212121"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121"> </span><span style="color:#212121"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121">A more detailed proposal - up to you; there are literally thousands of bugs in FX that I’d rather focus on instead, but it’s an open source and nobody can tell
you what to do :-) May be a more detailed proposal at least outlining public APIs might help.</span><span style="color:#212121"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121"> </span><span style="color:#212121"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121">Looking at your Carousel TreeViewSkin demo (nice work, by the way!) I fully agree - there is no way we can reasonably create a base skin for that. It is a new
skin, or maybe even a new control altogether.</span><span style="color:#212121"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121"> </span><span style="color:#212121"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121">The separation between skins and behaviors are fuzzy, but we do have an established and well know pattern: MVC. Behavior is the controller in this paradigm -
a stateful logic which translates input events into changes in model. You are proposing for B to translate the input events to another set of events which I think is unnecessary. “Everything should be made as simple as possible, but not simpler”, to paraphrase
Herr Einstein. May be I don’t see a clear use case (for new events)?</span><span style="color:#212121"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121"> </span><span style="color:#212121"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121">A behavior listens for events (coming from control or elements of skin), maintains its state, translates these events into direct actions on the model or the
control (control being a façade). I think there is no need for an extra layer of events, especially if they bubble up.</span><span style="color:#212121"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121"> </span><span style="color:#212121"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121">Most use case I think are limited to developers changing a minor aspect of the skin/behavior - adding a corner node between horizontal and vertical scroll bar
for example, or modifying the way currently selected item is highlighted vs. the mouse hover highlight, remap a key binding, or something like that. Go beyond that - it’s a new thing altogether, as you rightfully said earlier.</span><span style="color:#212121"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121"> </span><span style="color:#212121"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121">Also, when looking at sufficiently complex control such as (Rich)TextArea or TreeTableView - I don’t think the behavior can be composited from a bunch of simple
things - there is too much interaction. So B ends up being a complex, stateful beast that tightly coupled with the particular implementation of the skin (so in some sense you are right, saying we have only skins). Just like ComponentUI in swing. It simply
cannot be an interface or a singleton.</span><span style="color:#212121"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121"> </span><span style="color:#212121"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121">I am sorry, John, for my negative reaction to your proposal. I am very grateful for the discussion, and I think we should discuss/develop some ideas in it further
- like prioritization of event handlers.</span><span style="color:#212121"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121"> </span><span style="color:#212121"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121">What do you think we ought to do to move forward?</span><span style="color:#212121"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121"> </span><span style="color:#212121"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121">Thank you</span><span style="color:#212121"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16";color:#212121">-andy</span><span style="color:#212121"><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">John Hendrikx <john.hendrikx@gmail.com><br>
<b>Date: </b>Tuesday, October 17, 2023 at 15:04<br>
<b>To: </b>Andy Goryachev <andy.goryachev@oracle.com>, openjfx-dev@openjdk.org <openjfx-dev@openjdk.org><br>
<b>Subject: </b>Re: [External] : Re: [Request for Comments] Behavior / InputMap<o:p></o:p></span></p>
</div>
<p>Hi Andy,<o:p></o:p></p>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">On 17/10/2023 20:07, Andy Goryachev wrote:<o:p></o:p></span></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16 "">Dear John:</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16 ""> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16 "">It looks like we have different views on the subject, so perhaps we should invite other people to weigh in.</span><o:p></o:p></p>
</blockquote>
<p>I would be interested to hear from others on this subject as well.<o:p></o:p></p>
<p>I feel however that I may need to make a more formal proposal to show more clearly what is possible. I'd still be interested in hearing your views on the alternative proposal after I addressed your initial questions. Do you need more information?<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16 ""> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16 "">My goal is to move forward adding missing features without making any drastic changes, and avoid regressions as much as possible. We also have to be mindful of the fact that
we are dealing with constrained resources, so any major development is very likely out of question. That’s why</span><o:p></o:p></p>
</blockquote>
<p>I don't think my proposal is that drastic, nor do I think it will be the cause of any major regressions. Nor do I agree that my alternative is that much harder to implement. It may require a bit more work upfront, but it also offers more in the end. It
still can be implemented one control at a time.<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16 ""> </span><o:p></o:p></p>
<p style="margin-left:.5in">My problem here is that by making this class public (which IMHO is not a good design) will lock us out of improving this later.
<o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16 "">If nobody uses FX there will be no “later”. If customers’ code breaks too often they will switch to some [unnamed] alternative.</span><o:p></o:p></p>
</blockquote>
<p>That's conditional on if we're breaking code, who said anything about that? Are you saying we can't change internals too much?<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p style="margin-left:.5in">Nothing Behavior related should be made public without a full design of how Behaviors should work, what their responsibilities are, how they interact with Skins (if at all, IMHO they shouldn't), etc. Once a design is known and agreed
upon, then we can work on step-by-step improvements by making parts public, and leaving parts hidden.<o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16 "">We kind of know what behaviors do - they handle user input, modifying the appearance or internal state of the control.</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16 ""> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16 "">I just want to mention again that behaviors must interact with skins - not all the behaviors, but some. For example, TextArea “MOVE_LINE_END” needs to know how the text is
laid out in order to determine the target caret position, this function cannot be implemented without the skin and the laid out text. I think we need to take into account this constraint.</span><o:p></o:p></p>
</blockquote>
<p>This is a technical issue that can be resolved. Tying Behaviors and Skins together just means we only have one thing: Skins. In that case, why pretend there even are behaviors? If Skins need to provide functionality, this can be achieved differently.
TextArea could provide overridable hooks for this, Skins could install an event handler for TextAreaEvent.MOVE_LINE_END; just the fact that the TextArea skin is doing it this way is a red flag that clearly shows this class may need some adjustments as it was
clearly not well separated -- it's normal for such problems to appear when trying to introduce something new; you don't work around them, you solve them.<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16 ""> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16 "">Another point is that behavior is sometimes stateful, so let’s take this into account as well.</span><o:p></o:p></p>
</blockquote>
<p class="MsoNormal"><span style="font-size:11.0pt">I've taken it into account now, and state can be associated with behaviors easily enough, without having a behavior be both the state class and the factory. It's a minor separation, but makes it much easier
to reason about.<br>
<br>
<o:p></o:p></span></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16 ""> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16 "">I think BehaviorBase is just a convenient way to access the new input map (the subject of the new proposal). If someone does not want or does not need to use the input map
- fine, nothing in the proposed design requires them to use it. I don’t think it should be an interface either - the methods in BehaviorBase are protected because they are offered for subclasses only, and making BB an interface will turn these public which
isn’t right.</span><o:p></o:p></p>
</blockquote>
<p class="MsoNormal"><span style="font-size:11.0pt">I have a better solution for this, allowing Behavior to be an interface, with easy subclassing and composition options to manipulate the contained inputmap (without actually needing to expose an inputmap).<br>
<br>
<o:p></o:p></span></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16 ""> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16 "">I do acknowledge that the issue of ordering of calls to added handlers might be undefined/unexpected, especially after a skin change. This is the existing condition, and
we probably should try to solve it in a separate thread. I think that for skins the expectation is that the handlers added by the user are orthogonal to those added by the skin/behavior, and if they are not - use event filter, or let’s talk about adding prioritization
in a separate discussion.</span><o:p></o:p></p>
</blockquote>
<p class="MsoNormal"><span style="font-size:11.0pt">I always expected such a fix to be a separate change. It could even be delayed somewhat, but not forever. As the current implementation does not specify any ordering, there is sufficient freedom to make
minor adjustments here. Again, event filters are not intended and insufficient for this purpose.<br>
<br>
<o:p></o:p></span></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16 ""> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16 "">I also acknowledge that the input map proposal does not address the issue of creating alternative custom skins and extending behaviors beyond modifying the key mappings and
some limited manipulations of handlers. But, in my opinion, it adds substantial value to the application developers without upsetting the cart too much.</span><o:p></o:p></p>
</blockquote>
<p>Skins are sufficiently easy as it is, and I don't see it as a goal to do anything here, as long as we keep them separated not much thought needs to go here; designing Skins for possible extension (with well specified protected methods that can't be changed
anymore as they're API) is a near impossibility so I don't see that happening ever. FX Skins are just too complex for that (they're not really what people view traditionally as Skins, just some graphics that can be replaced).
<o:p></o:p></p>
<p>Skinning will IMHO remain a business of writing a complete new skin, as the options are endless and any customization of an existing Skin is bound to almost always run into a place where insufficient customization options will force the creation of a new
Skin -- you simply can't design for the unknowable. For example, I have Skins for ListView that turn it into a column based view, and one that turns it into a fully 3d animated image carousel (<a href="https://urldefense.com/v3/__https:/www.youtube.com/watch?v=8Mb15bOwIyE__;!!ACWV5N9M2RV99hQ!OI9hc6cUqJ-poC0z2krLl8yLq80ITMZf9oG0RF-IK9xfrErmMWvPWqrC9ZXvNvLIbxBHJT9b_nSoBSe-eWYdyUbCCOi6$">https://www.youtube.com/watch?v=8Mb15bOwIyE</a>)
-- there's just no way that could be achieved "customizing" ListViewSkin.<o:p></o:p></p>
<p>Behaviors are however much more limited, and not nearly as complex; they can be and should be extendible in the future.<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16 ""> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16 "">They say “better is the enemy of good”, which is apt in our case, though I hope we can somehow agree on a solution in a reasonable time.</span><o:p></o:p></p>
</blockquote>
<p>That's the rule for code that can be changed in the future :) For API's the rule is: if you aren't sure, then don't.<o:p></o:p></p>
<p>--John<o:p></o:p></p>
<p><o:p> </o:p></p>
</div>
</div>
</div>
</body>
</html>