Could you write a single skin that delegates to one or more reusable skins?

On Jan 7, 2014, at 7:26 AM, John Hendrikx <hj...@xs4all.nl> wrote:

> On 7/01/2014 14:50, Tomas Mikula wrote:
>> Interesting ideas. I'm wondering, do you switch skins often enough that you 
>> are worried about performance (and thus care about reusability of skins)? 
>> Because I don't see how reusability of skins saves you lines of code - 
>> whether the code is in the constructor or in the initialize() method, it is 
>> there somewhere. In my opinion, reusing objects is more complicated than 
>> creating fresh instances and the only justification for it is performance.
> 
> To address your last point first, if you already are required to write a 
> proper dispose method, then fresh instances should be just as easy/hard to 
> write as reusable ones.  Everything is already in place, just rename the 
> constructor.  Of course, if you did not write a proper dispose method, then 
> your object will stick around or cause other trouble.  With fresh instances 
> you won't notice this so readily -- in JavaFX for example, the problem of 
> having objects that are no longer actively reachable through the SceneGraph, 
> but are still participating in Event handling (because they registered 
> non-weak listeners) can be a nice source of surprises.  With reusable 
> objects, you'll notice the bugs in your cleanup code likely the first time 
> you reuse it.
> 
> Anyway, for me, making Skins reusable makes them easier to use with bindings, 
> and it ofcourse saves creating a factory.  I see the "skin" of an object as 
> the same as say its background color.  There is no reason (anymore I think) 
> that one should be treated so differently from the other.
> 
>   private final Skin someExistingSkin = new SkinA();
>   private final Skin someExistingSkin2 = new SkinB();
> 
>   void changeToSquareLook() {
>      myControl.setSkin(someExistingSkin);
>   }
> 
>   void changeToRoundLook() {
>      myControl.setSkin(someExistingSkin2);
>   }
> 
> vs.
> 
>  private final SkinFactory skinFactory = new SkinFactory() {
>     public Skin createSkin(Control control) {
>         return new SkinA(control);
>     }
>  };
> 
>  private final SkinFactory skinFactory2 = new SkinFactory() {
>     public Skin createSkin(Control control) {
>         return new SkinB(control);
>     }
>  };
> 
>  void changeToSquareLook() {
>     myControl.setSkin(skinFactory.createSkin(myControl));
>  }
> 
>   void changeToRoundLook() {
>     myControl.setSkin(skinFactory2.createSkin(myControl));
>   }
> 
> It's not really about performance, but ease of use.  The binding case 
> requires a ChangeListener instead of just bind().
> 
>> I agree with you on the problem of separation of skin initialization from 
>> setSkin(). Another way to address this could be deprecating the original 
>> setSkin() method and introducing
>> 
>>    setSkin(SkinProvider<C> skinProvider);
>> 
>> where SkinProvider is a SAM interface and thus the above method could be 
>> called like this:
>> 
>>    setSkin(control -> new MySkin(control));
>> 
>> I know this defeats reusability of skins altogether, so you (and others) may 
>> disagree.
> Maybe if there was a "skinProviderProperty"... then I could bind to that 
> atleast.  Still introduces lots of factories (or functions).
> 
> --John
> 

Reply via email to