Future of Skins
John Hendrikx
hjohn at xs4all.nl
Tue Jan 7 07:26:24 PST 2014
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
More information about the openjfx-dev
mailing list