只要可观察列表JavaFX的对象发生变化,就更新表视图UI



我有一个包含对象的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>

最新更新