我正在设计一个允许在 TableView
单元格上拖放的应用程序。
但是,一旦拖放完成并且单元格的值切换成功后,双击已进行拖放的单元格会使单元格变回拖放前的原始文本。
帮我解决这个问题。以下代码用于设置所有单元格的cellFactoryValue
。我是 javafx 新手。
private void setCellFactoryForColumns(TableColumn<TimeTable, String> col)
{
col.setCellFactory((TableColumn<TimeTable, String> e) -> {
TableCell<TimeTable, String> cell = new TableCell<TimeTable, String>() {
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setText(null);
setGraphic(null);
} else {
setText(item);
setGraphic(null);
}
}
};
col.setOnEditCommit((CellEditEvent<TimeTable, String> t) -> {
((TimeTable)t.getTableView().getItems().get(
t.getTablePosition().getRow())
).setDay(t.getNewValue());
});
cell.setOnDragDetected((MouseEvent event) -> {
Dragboard db = cell.startDragAndDrop(TransferMode.ANY);
ClipboardContent content = new ClipboardContent();
content.putString(cell.getText());
db.setContent(content);
cell.setStyle("-fx-background-color: red;"
+ "-fx-text-fill: white;");
cell.startEdit();
cell.setText("Dragged");
event.consume();
});
cell.setOnDragOver((DragEvent event) ->{
if(event.getGestureSource() != cell &&
event.getDragboard().hasString())
{
event.acceptTransferModes(TransferMode.MOVE);
cell.setStyle("-fx-background-color: green;"
+ "-fx-text-fill: white;");
}
event.consume();
});
cell.setOnDragEntered((DragEvent event) ->{
if(event.getGestureSource() != cell &&
event.getDragboard().hasString()){
cell.setStyle("-fx-background-color: yellow;");
}
event.consume();
});
cell.setOnDragExited((DragEvent event) -> {
cell.setStyle("-fx-background-color: grey;");
event.consume();
});
cell.setOnDragDropped((DragEvent event) -> {
Dragboard db = event.getDragboard();
boolean success = false;
if(db.hasString())
{
holdData = cell.getText();
cell.setText(db.getString());
success = true;
}
event.setDropCompleted(success);
event.consume();
});
cell.setOnDragDone((DragEvent event) ->{
if(event.getTransferMode() == TransferMode.MOVE)
{
cell.setText(holdData);
}
event.consume();
});
return cell;
});
}
最佳答案
您只需更改单元格中的文本,而不是项目的属性。因此,每次将新项目分配给 TableCell
时,旧值都会用作文本。
如果您将包含项目的单元格滚动到 View 之外,也会发生这种情况。
要解决此问题,请替换
cell.setText(db.getString());
和
cell.setText(holdData);
onDragDone
/onDragDropped
处理程序中的语句
update(cell, db.getString());
和
update(cell, holdData);
分别并实现 update
方法,如下所示:
static void update(TableCell<TimeTable, String> cell, String newValue) {
((TableRow<TimeTable>)cell.getTableRow()).getItem().setDay(newValue);
// the below line would be needed, if the setter does not trigger
// a update of the ObservableValue returned by the cellValueFactory
// cell.getTableView().refresh();
}
如果您的 cellValueFactory
返回一个允许写入项目的 WritableProperty
,则该方法可以编写为更通用的
static <I,P>void update(TableCell<I, P> cell, P newValue) {
WritableValue<P> property = (WritableValue<P>) cell.getTableColumn().getCellObservableValue(((TableRow<I>)cell.getTableRow()).getItem());
property.setValue(newValue);
}
关于java - 拖放事件完成后,如何在 javafx tablecell 中设置单元格值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38199385/