如何在tableView上区分服务器更新和用户更新?

时间:2019-08-17 04:28:32

标签: javafx

我试图从概念上理解 JavaFX 中的行为。我有一个TableView支持的ObservableList

现在,当服务器发送更新时,此ObservableList将直接或通过另一个ObservableList进行更新。

但是,用户可以更新同一张表-通过嵌入的boolean说出特定的CheckBoxTableCell属性列。

在此更新中,无需使用提交按钮,呼叫需要自动转到服务器。

如何区分此用户更新和服务器更新,否则可能出现无限循环?

因此,在下面的代码中,如果 list1 是服务器中的列表,则它将绑定到 list2 (用于绑定到{{1} },为避免混淆,这里没有显示。

除了绑定之外,我还可以使用侦听器来更新 list2

现在,如果用户通过编辑TableView在用户界面上更新了 list2 ,那么我只希望 list4 进行更改。我不希望在最初从服务器的 list1 中更新 list2 时更新 list4

完整代码详细信息: MainApp

TableRow

控制器

package com.personal.javafx1;

import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;


public class MainApp extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("/fxml/Scene.fxml"));

        Scene scene = new Scene(root);
        //scene.getStylesheets().add("/styles/Styles.css");

        stage.setTitle("JavaFX and Maven");
        stage.setScene(scene);
        stage.show();
    }

    /**
     * The main() method is ignored in correctly deployed JavaFX application.
     * main() serves only as fallback in case the application can not be
     * launched through deployment artifacts, e.g., in IDEs with limited FX
     * support. NetBeans ignores main().
     *
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}

FXML

package com.personal.javafx1;

import java.net.URL;
import java.util.*;
import java.util.ResourceBundle;
import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;

public class FXMLController implements Initializable {

    @FXML
    private Label label;

    @FXML
    private void handleButtonAction(ActionEvent event) {
        System.out.println("You clicked me!");
        label.setText("Hello World!");
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        ObservableList<String> list1 = FXCollections.observableArrayList("one", "two", "three");
        ObservableList<String> list2 = FXCollections.observableArrayList("4");
        ObservableList<String> list4 = FXCollections.observableArrayList("5");
        //FilteredList<String> list2 = list1.filtered(p -> true);

        list1.addListener((ListChangeListener) c -> {
            while (c.next()) {
                if (c.wasAdded()) {
                    //list2.addAll(c.getList());
                    System.out.println("items added to list 2 from list 1" + c);
                }
            }
        });

        list2.addListener((ListChangeListener) c -> {
            while (c.next()) {
                if (c.wasAdded()) {
                    System.out.println("items added to list 1 from list 2" + c);
                }
            }
        });

        list1.addAll("add1", "add2");
        System.out.println("list1" + list1);
        System.out.println("list2" + list2);
        System.out.println("list4" + list4);


    }    
}

1 个答案:

答案 0 :(得分:1)

您创建的ObservableList对象不会在属性更改时触发其任何侦听器。 TableView本身不提供任何用于修改items列表内容的功能,因此您可以将与服务器的通信添加到事件处理程序中,以修改列表内容。如果触发了列表的侦听器以更改其元素之一的属性,则可以使用onEditCommit截获该更改。 (请注意,即使返回的属性是WritableValue,这也需要您自行设置属性值。)这不适用于未过渡到编辑状态的单元格类型,例如{{1 }}。

对于这类更新,您可以简单地引入一个标记,您可以在基于服务器消息进行更新时修改该标记:

CheckBoxTableCell