i have treeview in cells must display different information according real implementation of treeitem's value.
my domain model looks like:
it seemed natural me split behaviour of "how display task in cell" or "how display group in cell" in 2 different classes.
public abstract class componenttreecell<t extends component> extends treecell<t> { @override protected void updateitem(t item, boolean empty) { //some common logic... } } public class grouptreecell extends componenttreecell<group> { @override protected void updateitem(group item, boolean empty) { super.updateitem(item, empty); //some group-specific-logic } } public class tasktreecell extends componenttreecell<task> { @override protected void updateitem(task item, boolean empty) { super.updateitem(item, empty); //some task-specific-logic } }
the following controller class contains treeview set cellfactory.
public class controller implements initializable { @fxml private treeview<component> treeview; @override public void initialize(url url, resourcebundle bundle) { treeview.setcellfactory(new callback<treeview<component>, treecell<component>>() { @override public treecell<component> call(treeview<component> arg0) { if(/* stuck */ instanceof group) { return new grouptreecell(); } else if(/* stuck */ instanceof task) { return new tasktreecell(); } else { return new defaulttreecell(); } } }); } }
but here stuck @ moment decide kind of cell have return. indeed have in parameter related treeview , not related treeitem !
it seems me kind of weakness of javafx. why javafx gives full treeview user when need retrieve 1 treecell ??
is there way in manner or have implement 2 different behaviour in same custom treecell implementation ?
public class componenttreecell extends treecell<component> { @override protected void updateitem(component item, boolean empty) { //some common logic... if(item instanceof group) { //group-specific logic... } else if(item instanceof task) { //task-specific logic... } else { //default logic... } } }
why javafx gives full treeview user when need retrieve 1 treecell ??
because there isn't 1-1 relationship between treeitem
s , treecell
s: treeview
create small number of treecell
s (even if tree has large number of items). treecell
s reused display different treeitem
s, example if nodes expanded/collapsed, or if user scrolls.
it done way performance. actual cells provide rendering quite large objects: ui components , carry css styling etc them. actual data displayed, i.e. treeitem
s relatively lightweight; simple wrappers string
s. mechanism allows have treeview
s huge amounts of data not impose huge burden on performance. creating treecell
every treeitem
not allow this.
because of this, treecell
provide factory has able handle treeitem
might given treeview
. example, user changes items displayed (by expanding/collapsing or scrolling), treecell
instance displaying task
might used display group
. purpose of updateitem(...)
method; called when treecell
reused.
this means setup won't work. need treecell<component>
implementation in last code example. of course factor configuration separate classes if like, like:
public class componenttreecell extends treecell<component> { @override protected void updateitem(component item, boolean empty) { super.updateitem(item, empty); cellconfiguratorfactory.getconfigurator(item).configure(this, item, empty); } }
factory:
public class cellconfiguratorfactory { private static cellconfigurator<task> taskcellconfigurator ; private static cellconfigurator<group> groupcellconfigurator ; private static cellconfigurator<component> defaultcellconfigurator ; private static cellconfigurator getconfigurator(component item) { if (item instanceof task) { if (taskcellconfigurator == null) { taskcellconfigurator = new taskcellconfigurator(); } return taskcellconfigurator ; } else if (item instanceof group) { if (groupcellconfigurator == null) { groupcellconfigurator = new groupcellconfigurator(); } return groupcellconfigurator ; } else { if (defaultcellconfigurator == null) { defaultcellconfigurator = new defaultcellconfigurator(); } return defaultcellconfigurator ; } } }
(note can afford assume factory ever used single thread, since happen on fx application thread.)
and
public interface cellconfigurator<t extends component> { public void configurecell(componenttreecell cell, t item, boolean empty); }
with, example,
public class taskcellconfigurator implements cellconfigurator<task> { public void configurecell(treecell<component> cell, task item, boolean empty) { // task-specific implementation... } }
however, i'm not sure additional structure worth effort here.
Comments
Post a Comment