mpcListView.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
@Override
public ListCell<String> call(ListView<String> param){
return new XCell();
}
});
public class XCell extends ListCell<String>{
HBox hbox = new HBox();
Label label = new Label();
Button button = new Button("",getImage());
String lastItem;
public XCell(){
super();
hbox.setSpacing(120);
hbox.getChildren().addAll(label,button);
button.setOnAction(new EventHandler<ActionEvent>(){
@Override
public void handle(ActionEvent event){
mpcListView.getItems().remove(lastItem);
}
});
}
@Override
protected void updateItem(String item, boolean empty){
super.updateItem(item, empty);
if (empty){
lastItem = null;
setGraphic(null);
}else{
lastItem = item;
label.setText(item);
setGraphic(hbox);
}
}
}
为什么要调用super.updateItem(item, empty)
?
答案 0 :(得分:3)
ListCell updateItem(...)实现非常重要,因为它调用Cell updateItem(...)实现来检查它是否为空并调用正确的方法:setItem(...)或setEmpty(.. )。
如果不调用super.updateItem(...),则不调用Cell.updateItem(...)并且不调用setItem(...)然后...没有绘制任何内容或者值是没有更新! ListCell在使用Cell updateItem实现之前只添加了一些检查,因此您有两个选择:
请注意,ListCell它不是ListView使用的“基础”实现。请参阅TextFieldListCell类,它是一个很好的例子,它实际上是如何工作的,从mercurial和read中获取源代码,它始终是最好的方法。
例如,TextFieldListCell使用super.updateItem(...)来调用Cell.updateItem实现以检查它是否为空(通过使用setItem或setEmpty),然后使用javafx.scene.control.cell.CellUtils。的updateItem(...)。此方法获取在当前单元格中设置的项目,然后在项目上使用转换器以在标签中显示字符串。
答案 1 :(得分:2)
ListCell的默认实现执行一些标准的内务处理。例如,它注册了一个鼠标监听器,可以适当地更新ListView的选择模型。
super.updateItem(...)
调用调用该方法的超类实现。如果省略它,那么选择就不会起作用,并且可能还有很多其他功能也无法正常工作。
在您的代码中,lastItem
字段是多余的。已经在ListCell类中定义了item
属性:updateItem(...)的默认实现所做的另一个工作是更新此属性。因此,您可以省略该字段,只需在需要获取项目时调用getItem()
。
忘记拨打super.updateItem(...)
很容易。出于这个原因,我经常使用另一种方法:
mpcListView.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
@Override
public ListCell<String> call(ListView<String> param){
return createXCell();
}
});
public ListCell<String> createXCell() {
final ListCell<String> cell = new ListCell<String>();
final HBox hbox = new HBox();
final Label label = new Label();
final Button button = new Button("",getImage());
hbox.setSpacing(120);
hbox.getChildren().addAll(label,button);
button.setOnAction(new EventHandler<ActionEvent>(){
@Override
public void handle(ActionEvent event){
mpcListView.getItems().remove(cell.getItem());
}
});
cell.itemProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> obs, String oldValue, String newValue) {
if (newValue == null) {
cell.setText(null);
cell.setGraphic(null);
} else {
cell.setText(newValue);
cell.setGraphic(hbox);
}
}
});
return cell ;
}
请注意,我根本没有对ListCell进行子类化:我只使用默认实现,并使用itemProperty
上的侦听器更新文本和图形。这更符合&#34;更喜欢继承和#34;。