我有一个TableView,它使用ColorPicker来(显示/编辑)单元格中的颜色。该表在所需字段中显示ColorPicker,但编辑不起作用。
TableColumn<SeriesPreferences, Color> c2 = new TableColumn<SeriesPreferences, Color>("Color");
c2.setCellValueFactory(new PropertyValueFactory<SeriesPreferences, Color>("color"));
c2.setCellFactory(new Callback<TableColumn<SeriesPreferences, Color>,
TableCell<SeriesPreferences, Color>>()
{
@Override
public TableCell<SeriesPreferences, Color>
call(final TableColumn<SeriesPreferences, Color> param)
{
TableCell<SeriesPreferences, Color> cell =
new TableCell<SeriesPreferences, Color>()
{
@Override
public void updateItem(Color c, boolean empty)
{
if(c != null)
{
final ColorPicker cp = new ColorPicker();
cp.setValue(c);
setGraphic(cp);
cp.setOnAction(new EventHandler<javafx.event.ActionEvent>()
{
public void
handle(javafx.event.ActionEvent t)
{
getTableView().edit(getTableRow().getIndex(), param);
commitEdit(cp.getValue());
}
});
}
}
};
return cell;
}
});
c2.setOnEditCommit(new EventHandler<CellEditEvent<SeriesPreferences, Color>>()
{
@Override
public void handle(CellEditEvent<SeriesPreferences, Color> t)
{
((SeriesPreferences) t.getTableView().getItems().get(t.getTablePosition().
getRow())).setColor(t.getNewValue());
}
});
当我在颜色选择器中更改颜色时,不会调用编辑事件处理程序,有什么想法吗?
如果JavaFX POJO(或JavaFX Bean)的属性正确绑定到表,则无需直接访问它,也无需调用commitEdit以外的任何东西。
Max Beikirch的回答具有误导性,因为当表格不处于编辑模式时,它会导致颜色选择器(以及颜色)消失。将表置于编辑模式是一种变通方法,但效果不好。因此,在点击按钮时显示颜色选择器弹出窗口之前,请执行以下操作:
用这样的颜色选择器写你的单元格:
public class ColorTableCell<T> extends TableCell<T, Color> {
private final ColorPicker colorPicker;
public ColorTableCell(TableColumn<T, Color> column) {
this.colorPicker = new ColorPicker();
this.colorPicker.editableProperty().bind(column.editableProperty());
this.colorPicker.disableProperty().bind(column.editableProperty().not());
this.colorPicker.setOnShowing(event -> {
final TableView<T> tableView = getTableView();
tableView.getSelectionModel().select(getTableRow().getIndex());
tableView.edit(tableView.getSelectionModel().getSelectedIndex(), column);
});
this.colorPicker.valueProperty().addListener((observable, oldValue, newValue) -> {
if(isEditing()) {
commitEdit(newValue);
}
});
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
@Override
protected void updateItem(Color item, boolean empty) {
super.updateItem(item, empty);
setText(null);
if(empty) {
setGraphic(null);
} else {
this.colorPicker.setValue(item);
this.setGraphic(this.colorPicker);
}
}
}
如果您使用的是Java7,请用匿名内部类替换lambdas,但它应该也能工作。完整的博客文章在这里。
我对CheckBoxTableCell和DatePickerTableCell以及ColorPickerTableCells遇到了同样的问题:-(
我是这样处理的:在控件的事件上,我取回"((Inputs)getTableView().getItems().get(getTableRow().getIndex()"使用的POJO对象,并像在OnEditCommit方法中那样更新类似的对象。。。
所以对我来说,它看起来像这样(更新颜色):
((Inputs) getTableView().getItems().get(
getTableRow().getIndex())
).setColor(cp.getValue());
以下是ColorPickerCell的示例:
public class ColorPickerTableCell<Inputs> extends TableCell<Inputs, Color>{
private ColorPicker cp;
public ColorPickerTableCell(){
cp = new ColorPicker();
cp.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
commitEdit(cp.getValue());
updateItem(cp.getValue(), isEmpty());
((Inputs) getTableView().getItems().get(
getTableRow().getIndex())
).setColor(cp.getValue());
}
});
setGraphic(cp);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
setEditable(true);
}
@Override
protected void updateItem(Color item, boolean empty) {
super.updateItem(item, empty);
cp.setVisible(!empty);
this.setItem(item);
cp.setValue(item);
}
}
通过这个简单的JavaFX的POJO:
public ObjectProperty<Color> color = new SimpleObjectProperty<Color>();
this.color = new SimpleObjectProperty(color);
public ObjectProperty<Color> colorProperty() {
return color;
}
public void setColor(Color color2) {
color.set(color2);
}
我不知道这是否是实现这一目标的好方法,但它对我有效……注意,JavaFX的POJO只能在"ActionEvent"请求(组合框、日期选择器、颜色选择器等)中访问
问候,
好吧,我研究了一下这个话题,因为我也遇到过同样的问题。我恐怕只能说JavaFX是无法使用的。
我看了一下其他人是如何实现他们的单元格的,关键是他们都使用了可以用字符串表示的东西。现在,Java一直都是这样:要么用Java的方式,要么独自一人淋雨。JavaFX的文档目前非常糟糕,所以我不得不尝试,直到它工作为止。
所以:要触发editCommit
-事件,必须在updateItem()
中调用setContentDisplay(ContentDisplay. TEXT_ONLY)
。如果想将数据显示为字符串,这很好,但在这种情况下完全失败,因为颜色选择器只完成了这项工作。
或者,也可以手动触发事件。但是你是怎么得到桌子的位置的呢?我不知道。
就像Michael Simons在评论OP中所说的那样。您需要处于编辑模式。创建自己的自定义单元格时,可以通过在TableCell内部调用startEdit();
手动触发编辑模式。
例如,使用控件的focusProperty:
cp.focusedProperty().addListener((observable, oldValue, newValue) -> {
if (newValue) {
startEdit();
}
});