I think the interfaces may expose things that have been developed independently with different names but are the same thing.

For example, Window has the `showing` property, but effectively it works similar to `visible`.  The split between `Disable` and `Disabled` should be removed IMHO by making `MenuItem` implement `disabled` -- in other words, don't introduce two interfaces where one is desired.

The same goes for Properties and UserData; these serve a similar purpose and should IMHO be one interface.

Most of the names violate the "is-a" rule for interface naming, which will make code using it akward to read.  A suffic `Accessor` works pretty well, but for some there are perhaps nicer solutions; suggestions on that front:

    Disable/Disabled -> Disableable (dictionary: capable of being disabled)

    Properties/UserData -> UserPropertyAccessor

    Title -> Titled

    Text -> there's actually `Labeled` for that already, although done differently

    Visible -> tough one... Visualizable, Showable, VisibleAccessor

--John

On 08/09/2023 06:36, Michael Strauß wrote:
So far, I've identified these interfaces for the javafx.graphics module:

Visible:
Node, MenuItem, TableColumnBase

Disable:
Node, MenuItem, Tab

Disabled:
Node, Tab
(should MenuItem also have a "disabled" property? it doesn't currently)

Properties:
Window, Scene, Node, MenuItem, Tab, Toggle, ToggleGroup, TableColumnBase

UserData:
Window, Scene, Node, MenuItem, Tab, Toggle, ToggleGroup, TableColumnBase

Visible, Disable, and Disabled are useful because it allows reading
and managing some basic visual state of UI components.
Properties and UserData provide a common interface for objects that
can store arbitrary data.

Here are some interfaces that I would find questionable for the
javafx.graphics module:

Title:
Stage, DirectoryChooser, FileChooser

Text:
javafx.scene.text.Text, TextInputControl, Labeled, Tab, MenuItem,
TableColumnBase, Tooltip, Legend

Note: the "Text" interface might also belong to javafx.controls, but
then javafx.scene.text.Text couldn't implement it.


On Fri, Sep 8, 2023 at 3:07 AM Nir Lisker <nlis...@gmail.com> wrote:
I do something very similar in my own projects where I "decompose" my entities 
into such interfaces. I find it beneficial.

We do need to figure out which makes sense and for what purpose.

On Wed, Sep 6, 2023, 22:41 Andy Goryachev <andy.goryac...@oracle.com> wrote:
I think this proposal makes a lot of sense.



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.



What other traits/properties should we include?



Converting https://github.com/openjdk/jfx/pull/1215 to draft until this 
discussion comes to a resolution.



-andy





From: openjfx-dev <openjfx-dev-r...@openjdk.org> on behalf of Michael Strauß 
<michaelstr...@gmail.com>
Date: Saturday, September 2, 2023 at 15:09
To: openjfx-dev <openjfx-dev@openjdk.org>
Subject: JavaFX object traits

There's a proposal to add a common interface that identifies JavaFX
objects that can hold an Observable<Object, Object> property map:
https://github.com/openjdk/jfx/pull/1215

The reason for this is obvious: allow JavaFX objects that can hold
properties to be consumed by code without depending on brittle
`instanceof` checks. The problem is real, but I think we can do much
better than that.

Why have a common interface at all? Well, of course it allows
consumers to treat different objects in a uniform way. But there's
more to it: the interface specifies the _meaning_ of the method; it
guarantees that `Foo::getProperties` and `Bar::getProperties` are, in
fact, not only methods with the same name, but the same semantics.

`getProperties` and `hasProperties` is one example of such commonality
between dissimilar classes like `Node` and `MenuItem`. But I've come
across other examples in my own projects. For example, I'd like to
consume JavaFX objects that have the `visible` and `disable`
properties. Other applications will have different use cases, but
since we don't know all possible use cases, it's hard to come up with
a set of useful combinations of properties and methods.

However, I think we can use the Java type system to allow applications
to compose types that fit their unique use case.

We begin by identifying common properties, and create trait interfaces
that describe those properties:

     public final class javafx.scene.Trait {
         public interface Visible {
             BooleanProperty visibleProperty()
             default boolean isVisible()...
             default void setVisible(boolean value)...
         }
         public interface Disable {
             BooleanProperty disableProperty()
             default boolean isDisable()...
             default void setDisable(boolean value)...
         }
         public interface Properties {
             ObservableMap<Object, Object> getProperties()
             default boolean hasProperties()...
         }
         ...
     }

These interfaces can now be implemented by all relevant JavaFX
classes. This includes `Node`, `MenuItem`, and `Tab`, but applications
are free to implement these trait interfaces themselves.

Applications can now consume objects that implement any combination of
traits, which gives applications the much-needed flexibility to use
shared code for all kinds of JavaFX objects:

<T extends Trait.Properties & Trait.Visible>
void doSomething(T node) {
     node.getProperties().put("foo", "bar");
     node.setVisible(true);
}

<T extends Trait.Text & Trait.Graphic>
void doAnotherThing(T node) {
     node.setText("hello");
     node.setGraphic(myGraphic);
}

What do you think?

Reply via email to