<div dir="ltr"><div dir="auto">I do something very similar in my own projects where I "decompose" my entities into such interfaces. I find it beneficial.<div dir="auto"><br></div><div dir="auto">We do need to figure out which makes sense and for what purpose.</div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Sep 6, 2023, 22:41 Andy Goryachev <<a href="mailto:andy.goryachev@oracle.com" target="_blank">andy.goryachev@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div lang="EN-US" style="overflow-wrap: break-word;">
<div>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"Iosevka Fixed SS16"">I think this proposal makes a lot of sense.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"Iosevka Fixed SS16""><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"Iosevka Fixed SS16"">Having the trait interfaces inner classes of Trait clearly narrows down semantics. "Trait" might be too generic, maybe FxTrait or something like that? Just a thought.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"Iosevka Fixed SS16""><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"Iosevka Fixed SS16"">What other traits/properties should we include?<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"Iosevka Fixed SS16""><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"Iosevka Fixed SS16"">Converting
</span><span style="font-size:11pt"><a href="https://github.com/openjdk/jfx/pull/1215" rel="noreferrer" target="_blank">https://github.com/openjdk/jfx/pull/1215</a></span><span style="font-size:11pt;font-family:"Iosevka Fixed SS16""> to draft until this discussion comes to a resolution.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"Iosevka Fixed SS16""><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"Iosevka Fixed SS16"">-andy<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"Iosevka Fixed SS16""><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"Iosevka Fixed SS16""><u></u> <u></u></span></p>
<div id="m_1507663684924151361m_6242759579034381551mail-editor-reference-message-container">
<div>
<div style="border-right:none;border-bottom:none;border-left:none;border-top:1pt solid rgb(181,196,223);padding:3pt 0in 0in">
<p class="MsoNormal" style="margin-bottom:12pt"><b><span style="font-size:12pt;color:black">From:
</span></b><span style="font-size:12pt;color:black">openjfx-dev <<a href="mailto:openjfx-dev-retn@openjdk.org" rel="noreferrer" target="_blank">openjfx-dev-retn@openjdk.org</a>> on behalf of Michael Strauß <<a href="mailto:michaelstrau2@gmail.com" rel="noreferrer" target="_blank">michaelstrau2@gmail.com</a>><br>
<b>Date: </b>Saturday, September 2, 2023 at 15:09<br>
<b>To: </b>openjfx-dev <<a href="mailto:openjfx-dev@openjdk.org" rel="noreferrer" target="_blank">openjfx-dev@openjdk.org</a>><br>
<b>Subject: </b>JavaFX object traits<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11pt">There's a proposal to add a common interface that identifies JavaFX<br>
objects that can hold an Observable<Object, Object> property map:<br>
<a href="https://github.com/openjdk/jfx/pull/1215" rel="noreferrer" target="_blank">https://github.com/openjdk/jfx/pull/1215</a><br>
<br>
The reason for this is obvious: allow JavaFX objects that can hold<br>
properties to be consumed by code without depending on brittle<br>
`instanceof` checks. The problem is real, but I think we can do much<br>
better than that.<br>
<br>
Why have a common interface at all? Well, of course it allows<br>
consumers to treat different objects in a uniform way. But there's<br>
more to it: the interface specifies the _meaning_ of the method; it<br>
guarantees that `Foo::getProperties` and `Bar::getProperties` are, in<br>
fact, not only methods with the same name, but the same semantics.<br>
<br>
`getProperties` and `hasProperties` is one example of such commonality<br>
between dissimilar classes like `Node` and `MenuItem`. But I've come<br>
across other examples in my own projects. For example, I'd like to<br>
consume JavaFX objects that have the `visible` and `disable`<br>
properties. Other applications will have different use cases, but<br>
since we don't know all possible use cases, it's hard to come up with<br>
a set of useful combinations of properties and methods.<br>
<br>
However, I think we can use the Java type system to allow applications<br>
to compose types that fit their unique use case.<br>
<br>
We begin by identifying common properties, and create trait interfaces<br>
that describe those properties:<br>
<br>
public final class javafx.scene.Trait {<br>
public interface Visible {<br>
BooleanProperty visibleProperty()<br>
default boolean isVisible()...<br>
default void setVisible(boolean value)...<br>
}<br>
public interface Disable {<br>
BooleanProperty disableProperty()<br>
default boolean isDisable()...<br>
default void setDisable(boolean value)...<br>
}<br>
public interface Properties {<br>
ObservableMap<Object, Object> getProperties()<br>
default boolean hasProperties()...<br>
}<br>
...<br>
}<br>
<br>
These interfaces can now be implemented by all relevant JavaFX<br>
classes. This includes `Node`, `MenuItem`, and `Tab`, but applications<br>
are free to implement these trait interfaces themselves.<br>
<br>
Applications can now consume objects that implement any combination of<br>
traits, which gives applications the much-needed flexibility to use<br>
shared code for all kinds of JavaFX objects:<br>
<br>
<T extends Trait.Properties & Trait.Visible><br>
void doSomething(T node) {<br>
node.getProperties().put("foo", "bar");<br>
node.setVisible(true);<br>
}<br>
<br>
<T extends Trait.Text & Trait.Graphic><br>
void doAnotherThing(T node) {<br>
node.setText("hello");<br>
node.setGraphic(myGraphic);<br>
}<br>
<br>
What do you think?<u></u><u></u></span></p>
</div>
</div>
</div>
</div>
</div>
</blockquote></div>