Could you write a single skin that delegates to one or more reusable skins?
On Jan 7, 2014, at 7:26 AM, John Hendrikx <[email protected]> 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 >
