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