これを行う最も簡単な方法は、第三者のバインディングライブラリを使用する方法です.ReactFX 2.0には、hereと記載されているように、この機能が組み込まれています。あなたは
TableColumn<Person, String> lastNameColumn = new TableColumn<>("Last Name");
lastNameColumn.setEditable(true);
lastNameColumn.setCellFactory(tc -> {
TableCell<Person, String> cell = new TextFieldTableCell<>();
cell.editableProperty().bind(
// horrible cast needed because TableCell.tableRowProperty inexplicably returns a raw type:
Val.flatMap(cell.tableRowProperty(), row -> (ObservableValue<Person>)row.itemProperty())
.flatMap(Person::newRecordProperty)
.orElseConst(false));
return cell ;
});
を行うことができます使用して(明らかJavaFXのプロパティとメソッドを持つPerson
テーブルモデルオブジェクトを想定して)。
ライブラリがなければ、あなたはリスナーのかなり悲惨なネストされたリストが必要です。
TableColumn<Person, String> lastNameColumn = new TableColumn<>("Last Name");
lastNameColumn.setEditable(true);
lastNameColumn.setCellFactory(tc -> {
TableCell<Person, String> cell = new TextFieldTableCell<>();
ChangeListener<Boolean> newRecordListener = (obs, wasNewRecord, isNewRecord) -> updateEditability(cell);
ChangeListener<Person> rowItemListener = (obs, oldPerson, newPerson) -> {
if (oldPerson != null) {
oldPerson.newRecordProperty().removeListener(newRecordListener);
}
if (newPerson != null) {
newPerson.newRecordProperty().addListener(newRecordListener);
}
updateEditability(cell);
};
ChangeListener<TableRow> rowListener = (obs, oldRow, newRow) -> {
if (oldRow != null) {
((ObservableValue<Person>)oldRow.itemProperty()).removeListener(rowItemListener);
if (oldRow.getItem() != null) {
((Person)oldRow.getItem()).newRecordProperty().removeListener(newRecordListener);
}
}
if (newRow != null) {
((ObservableValue<Person>)newRow.itemProperty()).addListener(rowItemListener);
if (newRow.getItem() != null) {
((Person)newRow.getItem()).newRecordProperty().addListener(newRecordListener);
}
}
updateEditability(cell);
};
cell.tableRowProperty().addListener(rowListener);
return cell ;
});
、その後
private void updateEditability(TableCell<Person, String> cell) {
if (cell.getTableRow() == null) {
cell.setEditable(false);
} else {
TableRow<Person> row = (TableRow<Person>) cell.getTableRow();
if (row.getItem() == null) {
cell.setEditable(false);
} else {
cell.setEditable(row.getItem().isNewRecord());
}
}
}
を "レガシースタイル" APIを使用して代替が
TableColumn<Person, String> lastNameColumn = new TableColumn<>("Last Name");
lastNameColumn.setEditable(true);
lastNameColumn.setCellFactory(tc -> {
TableCell<Person, String> cell = new TextFieldTableCell<>();
cell.editableProperty().bind(
Bindings.selectBoolean(cell.tableRowProperty(), "item", "newRecord"));
return cell ;
});
です
私はこのオプションが嫌いです。なぜなら、型の安全性(またはコンパイラのチェックは全くありません)と広告以前のバージョンのJavaFXでは、「チェーン」内のプロパティのいずれかがnull値(この場合、頻繁に発生します)を持つ場合、ほとんど無限の警告メッセージを生成します。私は後者の問題は修正されていると信じていますが、これのReactFXバージョンははるかに優れています。
'TableColumn'と' TableCell'の両方に編集可能な状態があります。列を編集可能にして、セルの編集可能な状態を更新するセルファクトリを使用します。 'NewRecord'が不変の場合、' updateItem'メソッドでこれを簡単かつ直接行うことができます。それが変更可能ならば、 'newRecord'状態を適切に観察するためにリスナーとちょっとしたトリッキーが必要になります。 –
私はCellFactoryからそれをやろうとしましたが、そこからどうやって理解するのか正確には判断できませんでした。スニペットを提供できますか?それは私が必要なすべてかもしれません。ありがとう。 –
'newRecord'は変更可能ですか? –