API review: fix for TableViewBuilder- reference to create is ambiguous (RT-24272)

Eva Krejcirova eva.krejcirova at oracle.com
Mon Aug 27 08:02:56 PDT 2012


Hi Richard,

On 8/24/2012 4:14 PM, Richard Bair wrote:
> One question: you mention that this is a source incompatible change. But is it a runtime incompatible change? That is, if I have a JavaFX app already compiled against Java 6, and I run it on Java 7 or Java 8, will it break? Or is it only something I have to do to my sources at compile time?
If I tested it correctly, if you have JavaFX app which you compiled with 
JavaFX 2.2 (with any version of Java) you will be able to run it with 
JavaFX 8 after this change (because of type erasure).
This is the reason why I left the second version of create (<?, ?> 
create()) in the proposal - so that it hides the <?> create() from Region.

Eva

> Thanks
> Richard
>
> On Aug 24, 2012, at 6:50 AM, Eva Krejcirova wrote:
>
>> Hi All,
>>
>> We are having problems with the way our builders are created -
>>
>> Basically, this code:
>> ChoiceBoxBuilder.<String>create()
>>         .id("choiceBox")
>>         .items(FXCollections.observableArrayList("item1", "item2"))
>>         .build();
>>
>> or this one:
>>
>> TableView<Job>  tableView1 = TableViewBuilder.<Job>create();
>>
>> doesn't compile anymore in JavaFX 8.0 when using Java 7 - it fails with error: reference to create is ambiguous, both method create() in RegionBuilder and method<T>create() in ComboBoxBuilder match
>>         ComboBox<String>  combo = ComboBoxBuilder.<String>create().build();
>>   where T is a type-variable:
>>     T extends Object declared in method<T>create()
>>
>> Unfortunately there is no simple solution for this and the one I am proposing requires some incompatible API changes which are the reason for this email.
>>
>> First some background:
>> We didn't have this problem up until now because all ancestors of ChoiceBox and other controls were abstract, so there was just one create() method in their builders.
>> (this one: public static<T>  javafx.scene.control.ChoiceBoxBuilder<T, ?>  create() )
>> Now however, Control extends Region which is not an abstract class, which means that TableViewBuilder now extends RegionBuilder and inherits create() method from RegionBuilder (this one: public static javafx.scene.layout.RegionBuilder<?>  create()). And the compiler doesn't know which one of the create() methods to pick (Java 6 compiles this just fine, this issue manifest itself when compiled with Java 7).  Since the behavior of Java 7 is correct, this must be fixed on our side.
>>
>> My proposal is to add another create method to parametrized classes which would take the type as an argument e.g.
>>
>>     public static<T>  javafx.scene.control.ChoiceBoxBuilder<T, ?>  create(final Class<T>  type) {
>>         return new javafx.scene.control.ChoiceBoxBuilder();
>>     }
>>
>> and make the create() without arguments non-generic, so it hides the create in Region:
>>
>>     public static javafx.scene.control.ChoiceBoxBuilder<?, ?>  create() {
>>         return new javafx.scene.control.ChoiceBoxBuilder();
>>     }
>>
>> This way, the user can create the builder like this:
>> ChoiceBoxBuilder.create(String.class)
>>         .id("choiceBox")
>>         .items(FXCollections.observableArrayList("item1", "item2"))
>>         .build();
>>
>> Unfortunately this change will break some already existing code (but I don't see any better way for solving this).
>> E.g. this code:
>> ChoiceBox chb = ChoiceBoxBuilder.<String>create().items(FXCollections.observableArrayList("one", "two")).build();
>> will still not be compilable and will have to be rewritten (but at least there will be a way to do it).
>>
>> I already have the fix ready and I tested that it works but am open to other suggestions how to solve this problem if anybody has some better ones :-)
>>
>> Thanks,
>> Eva



More information about the openjfx-dev mailing list