我制作tableview,我有自定义TableCell应该提交丢失焦点的值和输入按钮我面临的问题是当我键入单元格并切换到另一个单元格时,它再次重新选择时呈现旧值它显示来自先前提交的正确值。 我不知道为什么它没有显示承诺的价值后细胞失去焦点它需要重新选择细胞更新它的价值我不知道我在这里缺少什么请帮助,这里是我的问题MCVE:
import javafx.event.Event;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.util.StringConverter;
public class EditCell<S, T> extends TableCell<S, T> {
// Text field for editing
// TODO: allow this to be a plugable control.
private final TextField textField = new TextField();
// Converter for converting the text in the text field to the user type, and vice-versa:
private final StringConverter<T> converter ;
public EditCell(StringConverter<T> converter) {
this.converter = converter ;
itemProperty().addListener((obx, oldItem, newItem) -> {
if (newItem == null) {
setText(null);
} else {
setText(converter.toString(newItem));
}
});
setGraphic(textField);
setContentDisplay(ContentDisplay.TEXT_ONLY);
textField.setOnAction(evt -> {
commitEdit(this.converter.fromString(textField.getText()));
});
textField.focusedProperty().addListener((obs, wasFocused, isNowFocused) -> {
if (! isNowFocused) {
commitEdit(this.converter.fromString(textField.getText()));
}
});
textField.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
if (event.getCode() == KeyCode.ESCAPE) {
textField.setText(converter.toString(getItem()));
cancelEdit();
event.consume();
} else if (event.getCode() == KeyCode.RIGHT) {
getTableView().getSelectionModel().selectRightCell();
event.consume();
} else if (event.getCode() == KeyCode.LEFT) {
getTableView().getSelectionModel().selectLeftCell();
event.consume();
} else if (event.getCode() == KeyCode.UP) {
getTableView().getSelectionModel().selectAboveCell();
event.consume();
} else if (event.getCode() == KeyCode.DOWN) {
getTableView().getSelectionModel().selectBelowCell();
event.consume();
}
});
}
/**
* Convenience converter that does nothing (converts Strings to themselves and vice-versa...).
*/
public static final StringConverter<String> IDENTITY_CONVERTER = new StringConverter<String>() {
@Override
public String toString(String object) {
return object;
}
@Override
public String fromString(String string) {
return string;
}
};
/**
* Convenience method for creating an EditCell for a String value.
* @return
*/
public static <S> EditCell<S, String> createStringEditCell() {
EditCell<S, String> cell = new EditCell<S, String>(IDENTITY_CONVERTER);
cell.setOnMouseClicked(e -> {
if (!cell.isEditing() && !cell.isEmpty()) {
cell.getTableView().edit(cell.getIndex(), cell.getTableColumn());
}
});
return cell;
}
// set the text of the text field and display the graphic
@Override
public void startEdit() {
super.startEdit();
textField.setText(converter.toString(getItem()));
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
textField.requestFocus();
}
// revert to text display
@Override
public void cancelEdit() {
super.cancelEdit();
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
// commits the edit. Update property if possible and revert to text display
@Override
public void commitEdit(T item) {
// This block is necessary to support commit on losing focus, because the baked-in mechanism
// sets our editing state to false before we can intercept the loss of focus.
// The default commitEdit(...) method simply bails if we are not editing...
if (! isEditing() && ! item.equals(getItem())) {
TableView<S> table = getTableView();
if (table != null) {
TableColumn<S, T> column = getTableColumn();
CellEditEvent<S, T> event = new CellEditEvent<>(table,
new TablePosition<S,T>(table, getIndex(), column),
TableColumn.editCommitEvent(), item);
Event.fireEvent(column, event);
}
}
super.commitEdit(item);
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
}
import java.io.Serializable;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class DailyDetails implements Serializable {
private Double dailyDebit;
private Double dailyCredit;
private String dailyDetails;
public DailyDetails() {
}
public Double getDailyDebit() {
return dailyDebit;
}
public void setDailyDebit(Double dailyDebit) {
this.dailyDebit = dailyDebit;
}
public Double getDailyCredit() {
return dailyCredit;
}
public void setDailyCredit(Double dailyCredit) {
this.dailyCredit = dailyCredit;
}
public String getDailyDetails() {
return dailyDetails;
}
public void setDailyDetails(String dailyDetails) {
this.dailyDetails = dailyDetails;
}
public StringProperty dailyDebitProperty() {
if (dailyDebit != null) {
return new SimpleStringProperty(dailyDebit.toString());
} else {
return new SimpleStringProperty("");
}
}
public StringProperty dailyCreditProperty() {
if (dailyCredit != null) {
return new SimpleStringProperty(dailyCredit.toString());
} else {
return new SimpleStringProperty("");
}
}
public StringProperty dailyDetailsProperty() {
if (dailyDetails != null) {
return new SimpleStringProperty(dailyDetails);
} else {
return new SimpleStringProperty("");
}
}
}
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class HalTest extends Application {
private ObservableList<DailyDetails> details = FXCollections.<DailyDetails>observableArrayList();
TableColumn<DailyDetails, String> dailyDebit;
TableColumn<DailyDetails, String> dailyCredit;
TableColumn<DailyDetails, String> dailyDetails;
@Override
public void start(Stage primaryStage) {
TableView<DailyDetails> table = new TableView<>();
table.getSelectionModel().setCellSelectionEnabled(true);
table.setEditable(true);
for (int i = 0; i < 10; i++) {
DailyDetails n = new DailyDetails();
n.setDailyCredit(Double.valueOf(0));
n.setDailyDebit(Double.valueOf(0));
n.setDailyDetails("Test " + i);
details.add(n);
}
table.setItems(details);
dailyDebit = new TableColumn<>("Daily Debit");
dailyDebit.setCellValueFactory(cellData -> cellData.getValue().dailyDebitProperty());
dailyDebit.setCellFactory(column -> EditCell.createStringEditCell());
dailyCredit = new TableColumn<>("Daily Credit");
dailyCredit.setCellValueFactory(cellData -> cellData.getValue().dailyCreditProperty());
dailyCredit.setCellFactory(column -> EditCell.createStringEditCell());
dailyDetails = new TableColumn<>("Daily Note");
dailyDetails.setCellValueFactory(cellData -> cellData.getValue().dailyDetailsProperty());
dailyDetails.setCellFactory(TextFieldTableCell.<DailyDetails>forTableColumn());
dailyDebit.setOnEditCommit(event -> {
event.getRowValue().setDailyDebit(Double.valueOf(event.getNewValue()));
});
dailyCredit.setOnEditCommit(event -> {
event.getRowValue().setDailyCredit(Double.valueOf(event.getNewValue()));
});
dailyDetails.setOnEditCommit(event -> {
event.getRowValue().setDailyDetails(event.getNewValue());
});
table.getColumns().add(dailyDebit);
table.getColumns().add(dailyCredit);
table.getColumns().add(dailyDetails);
/*table.setOnKeyPressed(event -> {
TablePosition<DailyDetails, ?> pos = table.getFocusModel().getFocusedCell();
if (pos != null && event.getCode().isLetterKey()) {
table.edit(pos.getRow(), pos.getTableColumn());
}
});*/
StackPane root = new StackPane();
root.getChildren().add(table);
Scene scene = new Scene(root, 500, 300);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}