我有一个包含对象的ObservableList的DataModel。
public class ExtractDataModel {
private final ObservableList<ExtractInfo> extractInfoList;
private final ObjectProperty<ExtractInfo> currentExtractInfo = new SimpleObjectProperty<>(null);
public ObservableList<ExtractInfo> getExtractInfoList(){
return extractInfoList;
}
public final void setExtractInfoList(ObservableList<ExtractInfo> _extractInfoList){
extractInfoList.setAll(_extractInfoList);
}
getters, setters ...
public ExtractDataModel(){
extractInfoList = FXCollections.observableList(new ArrayList<>(),ExtractInfo.extractor());
}
}
我的控制器
public class ExtractTabController {
private ExtractDataModel extractDataModel;
@FXML
private TableColumn<ExtractInfo, Double> progressCol;
@FXML
private TableView<ExtractInfo> extractTable;
other columns ...
public void initialize() {
extractTable.setItems(sortedExtractInfoList);
progressCol.setCellValueFactory(new PropertyValueFactory<ExtractInfo, Double>("progress"));
progressCol.setCellFactory(ProgressBarTableCell.<ExtractInfo>forTableColumn());
}
public ExtractTabController(ExtractDataModel _extractDataModel) {
System.out.println("Call constructor in extract controller");
this.extractDataModel = _extractDataModel;
}
}
ExtractInfo's extractor
定义如下
public class ExtractInfo {
private final StringProperty tableName = new SimpleStringProperty();
private final StringProperty fields = new SimpleStringProperty();
other fields ...
private DoubleProperty progress = new SimpleDoubleProperty();
public DoubleProperty getProgressProperty() {
return this.progress;
}
public Double getProgress() {
return this.progress.get();
}
public void setProgress(Double progress) {
this.progress.set(progress);
}
public static Callback<ExtractInfo, Observable[]> extractor() {
return (ExtractInfo extractInfo) -> new Observable[]{extractInfo.getTableNameProperty(),
extractInfo.getFieldsProperty(),
extractInfo.getProgressProperty(),
extractInfo.getLimitRowsPerFileProperty(),
extractInfo.getLimitRowsProperty(),
extractInfo.getExtractFileNameProperty(),
extractInfo.checkBoxValueProperty()};
}
我的表格视图将使用setItems(extractDataModel.getExtracInfoList())
我的目标是,每当setters对ExtractInfo
进行更改时,TableView也会更新其UI
我创建了一个函数来测试我的数据模型
public void testUpdateUI(){
for(ExtractInfo ei: extractInfoList){
// Update extractInfoList but not table view UI
ei.setProgress(Double.valueOf("1");
// This will update table view UI - also change extractInfoList second time by remove then add new item
// Don't want to add this line
extractInfoList.set(extractInfoList.indexOf(ei),ei)
}
}
我可以简单地使用extractInfo.setProgress()
来更新表视图吗?使用上面的代码更新表视图UI被认为是作弊还是不好的做法?
尝试使用提取器作为显示,但不起作用。
将所有getXXProperty更改为xxProperty即可。
下面是一个较小的例子:
public class ExtractDataModel {
private ObservableList<ExtractInfo> extractInfoList;
public ExtractDataModel() {
extractInfoList = FXCollections.observableList(new ArrayList(), ExtractInfo.extractor());
ObservableList<ExtractInfo> extractInfoList = FXCollections.observableArrayList();
extractInfoList.add(new ExtractInfo(0.1));
extractInfoList.add(new ExtractInfo(0.4));
extractInfoList.add(new ExtractInfo(0.7));
extractInfoList.add(new ExtractInfo(0.3));
setExtractInfoList(extractInfoList);
}
public ObservableList<ExtractInfo> getExtractInfoList() {
return extractInfoList;
}
public void setExtractInfoList(ObservableList<ExtractInfo> _extractInfoList) {
extractInfoList.setAll(_extractInfoList);
}
}
public class ExtractInfo {
private DoubleProperty progress = new SimpleDoubleProperty();
public DoubleProperty progressProperty() {
return this.progress;
}
public Double getProgress(){
return this.progress.get();
}
public void setProgress(Double _progress) {
this.progress.set(_progress);
}
public static Callback<ExtractInfo, Observable[]>extractor(){
return (ExtractInfo extractInfo) -> new Observable[]{
extractInfo.progressProperty()
};
}
public ExtractInfo(Double _progress){
setProgress(_progress);
}
}
public class ExtractTabController {
private ExtractDataModel extractDataModel;
@FXML
private TableView<ExtractInfo> extractTable;
@FXML
private TableColumn<ExtractInfo, Double> progressCol;
public ExtractTabController(ExtractDataModel _extractDataModel){
System.out.println("Call constructor extract tab controller");
this.extractDataModel = _extractDataModel;
System.out.println(_extractDataModel.getExtractInfoList());
}
public void initialize(){
progressCol.setCellValueFactory(new PropertyValueFactory<ExtractInfo, Double>("progress"));
progressCol.setCellFactory(ProgressBarTableCell.<ExtractInfo>forTableColumn());
extractTable.setItems(extractDataModel.getExtractInfoList());
}
@FXML
public void updateUI(){
for(ExtractInfo extractInfo : extractDataModel.getExtractInfoList()){
extractInfo.setProgress(1.0);
}
}
}
public class App extends Application {
@Override
public void start(Stage primaryStage) {
ExtractDataModel model = new ExtractDataModel();
Parent root = null;
try {
FXMLLoader mainFxmlLoader = new FXMLLoader();
mainFxmlLoader.setLocation(getClass().getResource("ExtractTab.fxml"));
Callback<Class<?>, Object> controllerFactory = new Callback<Class<?>, Object>() {
ExtractTabController extractTabController = new ExtractTabController(model);
@Override
public Object call(Class<?> type) {
if (type == ExtractTabController.class) {
System.out.println("Return controller !");
return extractTabController;
}
return null;
};
};
mainFxmlLoader.setControllerFactory(controllerFactory);
root = mainFxmlLoader.load();
}
catch(Exception e){
}
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
XML
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/15.0.1" fx:controller="javafxapplication2.ExtractTabController">
<children>
<TableView fx:id="extractTable" layoutX="72.0" layoutY="70.0" prefHeight="200.0" prefWidth="200.0">
<columns>
<TableColumn fx:id="progressCol" prefWidth="75.0" text="C1" />
</columns>
</TableView>
<Button layoutX="308.0" layoutY="157.0" mnemonicParsing="false" onAction="#updateUI" text="Button" />
</children>
</AnchorPane>