java - Define custom Comparator for JavaFX TableView Column rendered as SimpleObjectProperty<ImageView> -
i have table has different columns , signature of 1 want add custom comporator :
@fxml private tablecolumn<media,simpleobjectproperty<imageview>> hasbeenplayed;
so column rendered imageview . has 2 possible states , either imageview
have null
image or imageview
have image , specific 1 have defined .
so want sorting based on if imageview
has null image , if imageview has image , made below comparator reports error don't know why...
hasbeenplayed.setcomparator( new comparator<simpleobjectproperty<imageview>>() { @override public int compare(simpleobjectproperty<imageview> o1 , simpleobjectproperty<imageview> o2) { if (o1.get().getimage() == o2.get().getimage()) return 0; return -1; } });
i should use lambda expression above , added in way more obvious trying achieve.
the error getting ..
exception in thread "javafx application thread" java.lang.classcastexception: javafx.scene.image.imageview cannot cast javafx.beans.property.simpleobjectproperty
as james_d requested on comments:
cell value factory:
hasbeenplayed.setcellvaluefactory(new propertyvaluefactory<>("hasbeenplayed"));
part of model media
:
public abstract class media { ..... /** has been played. */ private simpleobjectproperty<imageview> hasbeenplayed; ..... /** * checks been played property. * * @return simple object property */ public simpleobjectproperty<imageview> hasbeenplayedproperty() { return hasbeenplayed; }
}
there multiple issues code.
first of you're putting ui elements in item class, should avoid. name of column hints @ displayed property have 2 states. boolean property more appropriate.
use custom cellfactory
display image.
furthermore according error message real type of column should tablecolumn<media, imageview>
.
also you're violating contract of comparator
making non-symetric.
you have ensure following fulfilled:
if comparator.compare(a, b) < 0
comparator.compare(b, a) > 0
. in case not fulfilled unless imageview
s contain same image (or contain null
).
modify code in addition making property boolean property:
@fxml private tablecolumn<media, boolean> hasbeenplayed;
hasbeenplayed.setcomparator((v1, v2) -> boolean.compare(v1, v2));
or alternatively
hasbeenplayed.setcomparator((v1, v2) -> -boolean.compare(v1, v2));
and add following initialize
method of controller
final image playedimage = new image(...); hasbeenplayed.setcellfactory(col -> new tablecell<media, boolean>() { private final imageview image = new imageview(); { setgraphic(image); image.setfitwidth(playedimage.getwidth()); image.setfitheight(playedimage.getheight()); } @override protected void updateitem(boolean item, boolean empty) { super.updateitem(item, empty); // set image according played state image.setimage(item != null && item ? playedimage : null); } });
Comments
Post a Comment