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

Eva Krejcirova eva.krejcirova at oracle.com
Fri Aug 24 06:50:10 PDT 2012


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