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?