Lombok: Please Create JavaFX property annotation

Created on 14 Jul 2015  路  42Comments  路  Source: projectlombok/lombok

_Migrated from Google Code (issue 448)_

Most helpful comment

:bust_in_silhouette: [email protected]   :clock8: Feb 14, 2013 at 03:20 UTC

Please create @ FXProperty annotation that generates the JavaFX property methods:

e.g.

@ FXProperty
ObjectProperty<Customer> customer = new SimpleObjectProperty<>();

to Generate

public Customer getCustomer() {
return customer.get();
}

public void setCustomer(Customer c) {
customer.set(c);
}

public ObjectProperty<Customer> customerProperty() {
return customerProperty;
}

http://docs.oracle.com/javafx/2/binding/jfxpub-binding.htm

Thank you for Lombok project, I really appreaciate it.

All 42 comments

:bust_in_silhouette: [email protected]   :clock8: Feb 14, 2013 at 03:20 UTC

Please create @ FXProperty annotation that generates the JavaFX property methods:

e.g.

@ FXProperty
ObjectProperty<Customer> customer = new SimpleObjectProperty<>();

to Generate

public Customer getCustomer() {
return customer.get();
}

public void setCustomer(Customer c) {
customer.set(c);
}

public ObjectProperty<Customer> customerProperty() {
return customerProperty;
}

http://docs.oracle.com/javafx/2/binding/jfxpub-binding.htm

Thank you for Lombok project, I really appreaciate it.

:bust_in_silhouette: [email protected]   :clock8: Feb 27, 2013 at 14:50 UTC

A good reference that describes possible implementations can be found at:

https://wikis.oracle.com/display/OpenJDK/JavaFX+Property+Architecture

See section "JavaFX Property Cook Book"

According to this document (see near the end of the introduction) Oracle used Lombok during initial JavaFX 2 development. Probably that code is still somewhere around and can be open-sourced?

:bust_in_silhouette: francescov235   :clock8: Oct 29, 2013 at 05:50 UTC

javafx properties are really verbose

:bust_in_silhouette: [email protected]   :clock8: Oct 29, 2013 at 06:06 UTC

Yes, Once you are used to lombok, they do make the code very verbose

:bust_in_silhouette: [email protected]   :clock8: Jun 27, 2015 at 22:26 UTC

I guess not many people are interested in this feature but if you guys could point me in the right direction I would gladly implement it and share the outcome.

_End of migration_

this would be really cool.

Duplicate of #1222.

Here the working link to _JavaFX Property Architecture_ document with the _Java Property Cook Book_ chapter inside:

https://wiki.openjdk.java.net/display/OpenJFX/JavaFX+Property+Architecture

IntelliJ IDEA had implemented this... This would be really cool in Lombok.

@marlontrujillo1080 I couldn't find it in IDEA. Could you provide more info about this feature?

@turikhay

Is not an annotations, it is a refactor. You just create the property, e.g.:

private StringProperty stringProperty = new SimpleStringProperty();

and go to > refactor > create Getters and Setters... IDEA detects the property and create the getters and setters properly...

See the duplicate issue. I have a mostly-working implementation for Eclipse, but until I see PR requests having more discussion I don't want to waste my time.

Hello, I would be pleased, if you could make this feature ready :-) Here is one example for a Property and the three posible outcomes.

One:

@getter @Setter @FxBean
private final LongProperty id = new SimpleLongProperty();

Would become:

public final LongProperty idProperty() {
return this.id;
}
public final long getId() {
return this.idProperty().get();
}
public final void setId(final long id) {
this.idProperty().set(id);
}

Two:

@getter @FxBean
private final LongProperty id = new SimpleLongProperty();

Would become:

public final ReadOnlyLongProperty idProperty() {
return this.id;
}
public final long getId() {
return this.idProperty().get();
}

Three:

@Setter @FxBean
private final LongProperty id = new SimpleLongProperty();

Would become:

public final WritableLongValue idProperty() {
return this.id;
}
public final void setId(final long id) {
this.idProperty().set(id);
}

This three cases have to be implemented for the folowing Property-Types:

BooleanProperty
DoubleProperty
FloatProperty
IntegerProperty
ListProperty
LongProperty
MapProperty
ObjectProperty
SetProperty
StringProperty

For more information about FX-Properties you could read this:
https://wiki.openjdk.java.net/display/OpenJFX/JavaFX+Property+Architecture

any news on this one?

@chrismaster
There are many tickets with this issue. @rspilker asked for the specification in the ticket #1222. But after I replied, after a while he closed the ticket as a duplicate. So it does not seem, the maintainers of the project want to do anything about the issue. This is the reason, I cant use lombok.
Greatings

I would also like to have this feature in Lombok. Getters and setters clutter code a lot.

This would be very useful and totally in the spirit of Lombok.

It's a shame this issue hasn't seen more support. GUIs in JavaFX have tons of properties, and getters and setters clutter up a _lot_ of the screen. It's a perfect place to use lombok.

I like this idea and think it also fulfils the lombok feature requirements. There are no new or special things required to implement this one, should be quite easy.

Question: The linked JavaFx documentation does not mention ReadOnly*Property and Writable*Property, I guess these classes are there for all of the built-in property classes but how should lombok handle custom implementations?

Question: The linked JavaFx documentation does not mention ReadOnly*Property and Writable*Property

Yes it does...There's a whole paragraphe named "Properties Can Be Read-Only":

A property can be an instance of Property or ReadOnlyProperty. While the implementation can take pains to ensure that the ReadOnlyProperty returned from the property getter is actually a different object from the property object used for storage, this is an implementation decision and not required by the pattern. Property extends from ReadOnlyProperty.

Property is writeable by default so there is no Writeable*Property.

@ogerardin Yeah, missed that small section and I obviously meant Writeable*Value as listed in the example by @matthias24. I have never used JavaFx in a real project so expect that I know nothing about it :smile:

Here's a few ideas.
Even though it's tempting to reuse existing annotations @Getter and @Setter, they already have a well defined meaning, and we should not change how they behave. So if you use @Getter or @Setter on a Property field, you should get a getter/setter for the property.
We could introduce corresponding annotations @FxGetter and @FxSetter, but if you read the JavaFX Property Architecture document, you see that the code to generate for both cases is very similar:

  • final getter
  • final setter (private if readonly)
  • property getter (with ReadOnly return type if read-only)

So I would be in favor of a unique annotation @FxProperty which would generate code for a read/write property, unless its attribute "readOnly" is set to true. (NB: the "set-only" example from @matthias24 does not seem to constitute a legal FX property according to the spec.)

Example 1:

    @FxProperty
    private ObjectProperty<U> thing = new SimpleObjectProperty<>();

    // Generates
    public ObjectProperty<U> thingProperty() {
        return thing;
    }
    public final U getThing() {
        return thing.get();
    }
    public final void setThing(U thing) {
        this.thing.set(thing);
    }

Example 2:

    @FXProperty(readOnly = true)
    private ObjectProperty<U> thing = new SimpleObjectProperty<>();

    // Generates
    public ReadOnlyObjectProperty<U> thingProperty() {
        return thing;
    }
    public final U getThing() {
        return thing.get();
    }
    private final void setThing(U thing) {
        this.thing.set(thing);
    }

As outlined by @matthias24 , all JavaFX native property types types should be handled, not just ObjectProperty.

And of course if one of the methods to generate already exists, Lombok should silently ignore it, as it usually does.

we need this

I still have no idea how to handle custom implementations, SetProperty, ListProperty and MapProperty. Generating a asdfProperty method is easy but what should the getter and setter methods return?

I still have no idea how to handle custom implementations, SetProperty, ListProperty and MapProperty. Generating a asdfProperty method is easy but what should the getter and setter methods return?

Nothing really different from other property types. Getter/setter should return/take ObservableSet<E>, ObservableList<E> and ObservableMap<K, V>

Here a more convenience example of a read only property. Without possibility for cast to writeable property.

private ReadOnlyStringWrapper text = new ReadOnlyStringWrapper();
public ReadOnlyStringProperty textProperty() { return text.getReadOnlyProperty(); }
public String getText() { return text.get(); }
public void setText(String text) { this.text.set(text); }

@falkoschumann

Here a more convenience example of a read only property. Without possibility for cast to writeable property.

The actual type of the property is an implementation decision, so I don't think Lombok should be concerned about that. To quote the reference document "While the implementation can take pains to ensure that the ReadOnlyProperty returned from the property getter is actually a different object from the property object used for storage, this is an implementation decision and not required by the pattern."
All Lombok should know is that if we declare the property to be read-only, the property getter should return the corresponding ReadOnly type, and the setter should be private.
So in your example, if you want the property getter to return text.getReadOnlyProperty() instead of just text, you should write the textProperty() method yourself so that Lombok does not generate it.

@ogerardin
Ok, I agree with you.

So these are the classes that @FxPropertyshould be applicable on:
Property type|Read-only property type|Getter/setter type
-|-|-
BooleanProperty|ReadOnlyBooleanProperty|boolean
DoubleProperty|ReadOnlyDoubleProperty|double
FloatProperty|ReadOnlyFloatProperty|float
IntegerProperty|ReadOnlyIntegerProperty|int
ListProperty<E>|ReadOnlyListProperty<E>|ObservableList<E>
LongProperty|ReadOnlyLongProperty|long
MapProperty<K,V>|ReadOnlyMapProperty<K,V>|ObservableMap<K,V>
ObjectProperty<T>|ReadOnlyObjectProperty<T>|T
SetProperty<E>|ReadOnlySetProperty<E>|ObservableSet<E>
StringProperty|ReadOnlyStringProperty|String

In addition, we should allow @FxProperty to be used on the generic interface type:
Property type|Read-only property type|Getter/setter type
-|-|-
Property<T>|ReadOnlyProperty<T>|T

Also: the patterns that we have seen so far correspond to the "Basic" and "Read-only" patterns as described in the JavaFX Property Architecture document, "JavaFX Property Cook Book" section, but there are many others: Basic Half-Lazy, Basic Half-Lazy With Default Value, Basic Lazy, Basic Lazy With Default Value, Basic Reacting To Changes, Reflection, Computed, etc. While the "reflection" ones don't make much sense for a generation tool like Lombok (except if static footprint is an issue), the variants with laziness and default value could be generated based on additional attributes of @FxProperty. However I think that the basic and read-only patterns are a good start and probably fit 90% of JavaFX properties.

@ogerardin Thanks for providing this missing details

Finished the first prototype: https://github.com/Rawi01/lombok/tree/javafx
Pre-compiled version: lombok.zip

Finished the first prototype: https://github.com/Rawi01/lombok/tree/javafx
Pre-compiled version: lombok.zip

Great!
I just did a quick test, and got into a use case where the type of my property is XProperty which extends SimpleObjectProperty<X>, and I get the error @FxProperty is only supported on predefined JavaFx property types.

Considering XProperty implements Property<X>, it should fall into the "generic interface case" above and be allowed.

This is something that can not be changed, lombok can not (at least not easy) figure out if a class implements another. We could simply assume that an annotated field always is a property but that way we still don't know how to map the property to the underlying type (the one that the getter returns).

This is something that can not be changed, lombok can not (at least not easy) figure out if a class implements another. We could simply assume that an annotated field always is a property but that way we still don't know how to map the property to the underlying type (the one that the getter returns).

Oh I was hoping that if the property type implements Property<X> we could extract the X type and use it for getter/setter...

In theory it is possible but it is usually not worth the effort and very error prone. Basically lombok can only work with the code in a single file. It should work if you assign your own property to a field that uses a predefined JavaFx type e.g. ObjectProperty<Custom> p = new YourCustomProperty().

In theory it is possible but it is usually not worth the effort and very error prone. Basically lombok can only work with the code in a single file. It should work if you assign your own property to a field that uses a predefined JavaFx type e.g.
ObjectProperty<Custom> p = new YourCustomProperty().

Fair enough!

Wow, any more progress on this? This would save me soooooo much time.

Wow, any more progress on this? This would save me soooooo much time.

@Rawi01 what's the status on this ?

@bigjane have you tried my branch/version? Is there anything that you miss?

@Rawi01 I think he's waiting for the functionality to be merged into the main project.

@Rawi01 Did you create a PR for this? I couldn't find any.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

YinAqu picture YinAqu  路  3Comments

gardenias picture gardenias  路  3Comments

delverdev picture delverdev  路  3Comments

rspilker picture rspilker  路  3Comments

merric picture merric  路  4Comments