我有一个具有不同列的表,我要添加自定义组件的那个的签名是这样的:
@FXML
private TableColumn<Media,SimpleObjectProperty<ImageView>> hasBeenPlayed;
因此该列呈现为ImageView。它有两种可能的状态,Imageview
将有null
图像,或ImageView
将有一个图像,我已定义的特定图像。
所以我想要的是排序基于我 f ImageView
有空图像,如果ImageView有图像,所以我做了下面的Comparator但是它报告错误我不知道为什么......
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;
}
});
我应该使用上面的lambda表达式,我以这种方式添加它以更加明显我想要实现的目标。
我得到的错误是......
Exception in thread "JavaFX Application Thread" java.lang.ClassCastException:
javafx.scene.image.ImageView cannot be cast to javafx.beans.property.SimpleObjectProperty
正如James_D对评论所要求的那样:
Cell Value Factory:
hasBeenPlayed.setCellValueFactory(new PropertyValueFactory<>("hasBeenPlayed"));
模型的一部分Media
:
public abstract class Media {
.....
/** The has been played. */
private SimpleObjectProperty<ImageView> hasBeenPlayed;
.....
/**
* Checks for been played property.
*
* @return the simple object property
*/
public SimpleObjectProperty<ImageView> hasBeenPlayedProperty() {
return hasBeenPlayed;
}
}
答案 0 :(得分:2)
您的代码存在多个问题。
首先,您将UI元素放在item类中,这是您应该避免的。列的名称提示显示的属性只有2个状态。布尔属性更合适。
使用自定义cellFactory
显示图片。
此外,根据错误消息,列的实际类型应为TableColumn<Media, ImageView>
。
此外,您违反了Comparator
的合同,使其成为非对称的。
您必须确保满足以下条件:
如果comparator.compare(a, b) < 0
则comparator.compare(b, a) > 0
。在您的情况下,除非所有ImageView
包含相同的图像(或全部包含null
),否则不会达到此目的。
除了使属性成为布尔属性外,还修改这样的代码:
@FXML
private TableColumn<Media, Boolean> hasBeenPlayed;
hasBeenPlayed.setComparator((v1, v2) -> Boolean.compare(v1, v2));
或者
hasBeenPlayed.setComparator((v1, v2) -> -Boolean.compare(v1, v2));
并将以下内容添加到控制器的initialize
方法
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 the image according to the played state
image.setImage(item != null && item ? playedImage : null);
}
});