problem with builders

Jose Martinez jmartine_1026 at yahoo.com
Tue Jul 17 04:51:31 PDT 2012


John, Eva,

Thank you for the detailed information.  Adding the <?> worked.

The reason for editting the builder after instantiation is because only common or shared attributes get set initially, further down some edits must be made, specifically text.
 
thanks
jose


________________________________
 From: Eva Krejcirova <eva.krejcirova at oracle.com>
To: openjfx-dev at openjdk.java.net 
Cc: jmartine_1026 at yahoo.com 
Sent: Tuesday, July 17, 2012 5:29 AM
Subject: Re: problem with builders
 
Hi Jose,

There is another solution for your problem - if you write your code like this, it should compile:
LabelBuilder<?> lb = LabelBuilder.create();
Label label = lb.text("txt").build();

Regards,
Eva

On 7/17/2012 8:44 AM, John Hendrikx wrote:
> This is because the Builder classes are actually generic to make it possible to subclass them, but still make it possible to return the correct type.  For example, a RectangleBuilder builds Rectangles, but it extends ShapeBuilder which builds Shapes.  In order for the extended ShapeBuilder to know it should return RectangleBuilder for the intermediate steps there is a generic parameter passed by RectangleBuilder:
> 
> public class RectangleBuilder<B extends RectangleBuilder<B>> extends ShapeBuilder<B>
> 
> B here is RectangleBuilder.
> 
> Now, because you are using raw types in your code (you did not specify the generic type for RectangleBuilder for example) and are calling methods that are not part of RectangleBuilder directly (fill is from ShapeBuilder) it cannot determine the correct type anymore when build is called.  You can resolve it by writing the code like this:
> 
>           Label label = LabelBuilder.create().text("txt").build();
>           StackPane sp = StackPaneBuilder.create().alignment(Pos.CENTER).build();
>           Rectangle r = RectangleBuilder.create().fill(Color.ALICEBLUE).build();
> 
> On a side note, I've written such Builder constructs before, and there is another way Oracle could have handled this -- they could have made the final Builder implementations non-generic and then you could write the code as you did -- it would however introduce another class for each builder...
> 
> public abstract class AbstractRectangleBuilder<B> extends AbstractShapeBuilder<B>
> 
> public final class RectangleBuilder extends AbstractRectangleBuilder<RectangleBuilder>
> 
> Now the final class, which is used by users, is not generic and can be used like you are doing without any problems at all.
> 
> --John
> 
> On 17/07/2012 03:55, Jose Martinez wrote:
>> 
>> I am having a problem with some of the builders.... maybe I'm doing something wrong.  If I instantiate a builder (e.g. LabelBuilder) then if I edit it (e.g. .text("txt") ) then the compiler complaints that the build() method is not present.  Its as if the .text() method does not returns a LabelBuilder.  It does not happen with all builders, I have not tested enough to pick up on a pattern.
>> 
>> Here are some examples.....
>> 
>> //will not compile
>>          LabelBuilder lb = LabelBuilder.create();
>>          Label label = lb.text("txt").build();
>>          //compiles
>>          StackPaneBuilder spb = StackPaneBuilder.create();
>>          StackPane sp = spb.alignment(Pos.CENTER).build();
>>          //will not compile
>>          RectangleBuilder rb = RectangleBuilder.create();
>>          Rectangle r = rb.fill(Color.ALICEBLUE).build();
>> 
>> thanks jose
>> 
> 


More information about the openjfx-dev mailing list