简体   繁体   English

每当可观察列表 JavaFX 的 object 发生变化时更新表视图 UI

[英]Update table view UI whenever there is a change in a object of observable list JavaFX

I have a DataModel that contain ObservableList of an object.我有一个包含 object 的 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());
    }

}

My controller我的 controller


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 is defined as below 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()};
    }

My table view will use setItems(extractDataModel.getExtracInfoList())我的表视图将使用setItems(extractDataModel.getExtracInfoList())

My goal is that whenever there is a change in ExtractInfo by setters TableView also update its UI我的目标是,每当 setter TableView 对ExtractInfo进行更改时,也会更新其 UI

I created a function to test that in my data model我创建了一个 function 来测试我的数据 model

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)
     }

}

Can I update table view by simply using extractInfo.setProgress() ?我可以通过简单地使用extractInfo.setProgress()来更新表视图吗? Is it consider as cheating or bad practice by using above code to update table view UI?使用上述代码更新表格视图 UI 是否被视为作弊或不良做法?

Tried to use extractor as showing but it doesn't work.尝试使用提取器作为显示,但它不起作用。

Change all getXXProperty to xxProperty will do the trick.将所有 getXXProperty 更改为 xxProperty 即可。

Here is smaller example:这是较小的示例:

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 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM