我需要在TableView中创建一个可编辑的单元格,并在更改提交后使其变为粗体。我可以单独制作这些东西,但不能将它们放在一起,因为它们是通过setCellFactory方法实现的。
以下是代码部分:
设置cellFactory
((TableColumn) lpAttributesTable.getColumns().get(1)).setCellFactory(
new Callback<TableColumn<LPAttributesTableObject,String>, TableCell<LPAttributesTableObject,String>>() {
@Override
public TableCell<LPAttributesTableObject,String> call(
TableColumn<LPAttributesTableObject,String> param) {
TextFieldTableCell<LPAttributesTableObject, String> editableTableCell =
new TextFieldTableCell<LPAttributesTableObject, String>(new StringConverter<String>() {
@Override
public String toString(String object) {
return object;
}
@Override
public String fromString(String string) {
return string;
}
})
{
@Override
public void updateItem(String item, boolean empty)
{
super.updateItem(item,empty);
if (item == null || empty) {
setText(null);
// setStyle("");
}
else
{
setText(item);
styleProperty().bind(
Bindings.when(getTableRow().selectedProperty()).
then("-f-font-weight:bold;").otherwise(""));
}
}
};
return editableTableCell;
}
});
LPAttributesTableObject
public class LPAttributesTableObject {
private String attribute;
private String value;
public LPAttributesTableObject(String _attribute, String _value)
{
this.attribute = _attribute;
this.value = _value;
}
public final String getAttribute() { return attribute; }
public final String getValue() { return value; }
public StringProperty attributeProperty() { return new SimpleStringProperty(attribute); }
public StringProperty valueProperty() { return new SimpleStringProperty(value); }
public final void setAttribute(String _attr) { this.attribute = _attr;}
public final void setValue(String _description) { this.value = _description;}
}
带模型绑定的表。请注意,我已经注释掉了仅限编辑的cellFactory
((TableColumn) lpattrsTable.getColumns().get(1)).setCellValueFactory(new PropertyValueFactory<LPAttributesTableObject,String>("value"));
// ((TableColumn) lpattrsTable.getColumns().get(1)).setCellFactory(TextFieldTableCell.forTableColumn(new DefaultStringConverter()));
目前的实施仅允许细胞编辑。
答案 0 :(得分:0)
请注意,只是绑定到所选属性将不起作用。此外,您需要保存项目已被编辑的事实。这可以使用项目的属性或ObservableMap
。
此外,您需要实际设置项目已编辑的信息。这可以通过覆盖commitEdit
方法来完成。
// external storage of edited states by index
ObservableMap<Number, Boolean> edited = FXCollections.observableHashMap();
TableColumn<LPAttributesTableObject, String> column = (TableColumn) lpAttributesTable.getColumns().get(1);
StringConverter<String> converter = new DefaultStringConverter();
column.setCellFactory(t -> new TextFieldTableCell<LPAttributesTableObject, String>(converter) {
private final BooleanBinding editedBinding = Bindings.booleanValueAt(edited, indexProperty());
{
editedBinding.addListener((a, b, newValue) -> setStyle(newValue ? "-fx-font-weight:bold;" : ""));
}
@Override
public void commitEdit(String newValue) {
if (!Objects.equals(newValue, getItem())) {
// save data that this index has been edited
edited.put(getIndex(), Boolean.TRUE);
}
super.commitEdit(newValue);
}
});
请注意,如果修改了表的项目列表,您可能需要修改映射。
使用存储的值类型,无论项目是否已编辑而不是简单String
,您都可以保持代码简单,即使项目列表已被修改:
public class EditableString {
private final boolean edited;
private final String value;
public EditableString(boolean edited, String value) {
this.edited = edited;
this.value = value;
}
public EditableString(String value) {
this(false, value);
}
public boolean isEdited() {
return edited;
}
public String getValue() {
return value;
}
}
StringConverter<EditableString> converter = new StringConverter<EditableString>() {
@Override
public String toString(EditableString object) {
return object == null ? null : object.getValue();
}
@Override
public EditableString fromString(String string) {
return string == null ? null : new EditableString(true, string);
}
};
TableColumn<LPAttributesTableObject, EditableString> column = (TableColumn) lpAttributesTable.getColumns().get(1);
column.setCellFactory(t -> new TextFieldTableCell<LPAttributesTableObject, EditableString>(converter) {
@Override
public void updateItem(EditableString item, boolean empty) {
super.updateItem(item, empty);
if (item != null && item.isEdited()) {
setStyle("-fx-font-weight: bold;");
} else {
setStyle("");
}
}
@Override
public void commitEdit(EditableString newValue) {
EditableString currentItem = getItem();
if (currentItem == null || newValue == null || !Objects.equals(newValue.getValue(), currentItem.getValue())) {
super.commitEdit(newValue);
} else {
// if the string is the same, keep the old value
super.commitEdit(currentItem);
}
}
});
请注意,这需要您将包含LPAttributesTableObject
的{{1}}的属性更改为包含String
的属性。
答案 1 :(得分:0)
最后,我的意思是它的工作原理。
StringConverter<EditableString> converter = new StringConverter<EditableString>() {
@Override
public String toString(EditableString object) {
System.out.println("bla bla");
return object == null ? null : object.toString();
}
@Override
public EditableString fromString(String string) {
System.out.println("bla");
return string == null ? null : new EditableString(true, string);
}
};
((TableColumn) lpAttributesTable.getColumns().get(1)).setCellValueFactory(new PropertyValueFactory<LPAttributesTableObject,EditableString>("val"));
((TableColumn) lpAttributesTable.getColumns().get(0)).setCellValueFactory(new PropertyValueFactory<LPAttributesTableObject,String>("attribute"));
TableColumn<LPAttributesTableObject, EditableString> col = (TableColumn) lpAttributesTable.getColumns().get(1);
col.setCellFactory(TextFieldTableCellEditable.<LPAttributesTableObject, EditableString>forTableColumn(converter));
我必须将现有的TextFieldTableCell对象扩展为:
public class TextFieldTableCellEditable<S,EditableString> extends TextFieldTableCell<S,EditableString> {
public static <S,EditableString> Callback<TableColumn<S,EditableString>, TableCell<S,EditableString>> forTableColumn(
final StringConverter<EditableString> converter) {
return list -> new TextFieldTableCellEditable<S, EditableString>(converter);
}
public TextFieldTableCellEditable(StringConverter<EditableString> converter) {
this.getStyleClass().add("text-field-table-cell");
setConverter(converter);
}
@Override
public final void updateItem(EditableString item, boolean empty) {
super.updateItem(item, empty);
if (item != null && ((sample.EditableString)item).isEdited()) {
setText(item.toString());
setStyle("-fx-font-weight: bold;");
} else if (item != null && !((sample.EditableString)item).isEdited()){
setStyle("");
setText(item.toString());
} else {
setStyle("");
setText(null);
}
}
@Override
public void commitEdit(EditableString newValue) {
EditableString currentItem = getItem();
if (currentItem == null || newValue == null || !Objects.equals(((sample.EditableString)newValue).getValue(), ((sample.EditableString)currentItem).getValue())) {
super.commitEdit(newValue);
} else {
// if the string is the same, keep the old value
super.commitEdit(currentItem);
}
}
}
LPAttributesTableObject如下所示:
public class LPAttributesTableObject {
private String attribute;
private EditableString val;
public LPAttributesTableObject(String _attribute, EditableString _value)
{
this.attribute = _attribute;
this.val = _value;
}
public String getAttribute() { return attribute.toString(); }
public EditableString getVal() { return val; }
public final EditableString getValue() { return val; }
public StringProperty attributeProperty() { return new SimpleStringProperty(attribute.toString()); }
public ObjectProperty<EditableString> valProperty() { return new SimpleObjectProperty<EditableString>(this,"value",val); }
public void setAttribute(String _attr) { this.attribute = _attr;}
public void setValue(EditableString _value) { this.val = _value;}
public void setVal(EditableString _val) { this.val = _val; }
public void setVal(String _val) { this.val.setValue(_val);}
}
EditableString看起来像这样:
public class EditableString {
private boolean edited;
private String string;
public EditableString(boolean edited, String val)
{
this.edited = edited;
this.string = val;
}
public EditableString(String val)
{
this.edited = false;
this.string = val;
}
public String getValue() { return string; }
public void setValue(String val) { this.string = val; }
public String toString() { return string; }
public boolean isEdited() { return edited; }
public void setValue(EditableString estr) { this.setValue(estr.getValue()); this.edited = estr.edited; }
}