JavaFX object traits
Michael Strauß
michaelstrau2 at gmail.com
Fri Sep 8 04:36:30 UTC 2023
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 <nlisker at 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.goryachev at 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-retn at openjdk.org> on behalf of Michael Strauß <michaelstrau2 at gmail.com>
>> Date: Saturday, September 2, 2023 at 15:09
>> To: openjfx-dev <openjfx-dev at 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?
More information about the openjfx-dev
mailing list