我有一個TableView,它使用MappingItem
對象填充。目標是在Excel源字段與數據庫字段之間創建映射。JavaFX TableView項目在UI中對錶格進行更改後不會更改
在TableView中我有兩列。一個是<MappingItem, String>
,代表Excel頭。另一個是<MappingItem, GoldplusField>
,代表一個數據庫字段。第二列的單元格是ComboBoxTableCell
,它具有來自我的數據庫的字段列表。
問題是,在更改第二列組合框中的選擇後,我的選擇不會更新MappingItem
。我試圖獲取選定的單元格並提取項目,但我總是得到空引用。
這是一個示例代碼:
package tableviewexample;
import javafx.application.Application;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.value.ObservableValue;
import javafx.collections.*;
import javafx.event.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.ComboBoxTableCell;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.StringConverter;
public class TableViewExample extends Application {
@Override
public void start(Stage primaryStage) {
TableView<MappingItem> table = new TableView<>();
// FIRST COLUMN
TableColumn<MappingItem, String> colA = new TableColumn<>("Excel Column");
colA.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<MappingItem, String>, ObservableValue<String>>() {
@Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<MappingItem, String> param) {
return new ReadOnlyObjectWrapper(param.getValue().getExcelColumnName());
}
});
//SECOND COLUMN
TableColumn<MappingItem, GoldplusField> colB = new TableColumn<>("Database Field Column");
colB.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<MappingItem, GoldplusField>, ObservableValue<GoldplusField>>() {
@Override
public ObservableValue<GoldplusField> call(TableColumn.CellDataFeatures<MappingItem, GoldplusField> param) {
return new ReadOnlyObjectWrapper(param.getValue().getGpField());
}
});
GoldplusField gp1 = new GoldplusField("T1", "fName", "First Name");
GoldplusField gp2 = new GoldplusField("T1", "phn", "Phone");
ObservableList<GoldplusField> fieldsList = FXCollections.observableArrayList(gp1, gp2);
colB.setCellFactory(ComboBoxTableCell.forTableColumn(new FieldToStringConvertor(), fieldsList));
colB.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<MappingItem, GoldplusField>>() {
public void handle(TableColumn.CellEditEvent<MappingItem, GoldplusField> e) {
GoldplusField gpf = colB.getCellData(table.getFocusModel().getFocusedItem());
System.out.println(gpf.getGpName());
MappingItem item = table.getSelectionModel().getSelectedItem();
System.out.println(item.getGpField().getGpName());
}
});
table.setEditable(true);
table.getColumns().addAll(colA, colB);
MappingItem mi1 = new MappingItem("name");
MappingItem mi2 = new MappingItem("phone");
ObservableList<MappingItem> miList = FXCollections.observableArrayList(mi1, mi2);
table.setItems(miList);
StackPane root = new StackPane();
root.getChildren().add(table);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
class FieldToStringConvertor extends StringConverter<GoldplusField> {
@Override
public String toString(GoldplusField object) {
if (object != null)
return object.getGpName();
else
return "";
}
@Override
public GoldplusField fromString(String string) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
class MappingItem {
private String excelColumnName;
private GoldplusField gpField;
public String getExcelColumnName() { return excelColumnName; }
public void setExcelColumnName(String excelColumnName) { this.excelColumnName = excelColumnName; }
public GoldplusField getGpField() { return gpField; }
public void setGpField(GoldplusField gpField) { this.gpField = gpField; }
public MappingItem(String columnName) {
this.excelColumnName= columnName;
}
public MappingItem(GoldplusField gpField) {
this.gpField = gpField;
}
public MappingItem(String columnName, GoldplusField gpField) {
this.excelColumnName = columnName;
this.gpField = gpField;
}
}
class GoldplusField {
private String table;
private String dbName;
private String gpName;
public String getDbName() { return dbName; }
public String getGpName() { return gpName; }
public String getTable() { return table; }
public void setDbName(String dbName) { this.dbName = dbName; }
public void setGpName(String gpName) { this.gpName = gpName; }
public void setTable(String table) { this.table = table; }
public GoldplusField(String table, String dbName, String gpName) {
this.dbName = dbName;
this.gpName = gpName;
this.table = table;
}
}
}
您是否嘗試過使用ComboBoxTableCell.forTableColumn(...) –
是的。沒有不同。 –
你還爲表列設置了setOnEditCommit(...)嗎? –