JavaFX TableView和ObservableList - 如何自动更新表?

时间:2016-06-10 16:40:11

标签: javafx

我知道有类似问题,并且在不同的日期,但我会在这里放一个SSCCE,并试着简单地问这个问题。

我希望能够更新数据模型,并使其上的任何视图自动更新,这样任何更新模型的调用者都不会知道目前的任何视图。这是我到目前为止学习/尝试过的,没有调用TableView.refresh()它不会更新。我错过了什么?

main.java:

package application;

import javafx.application.Application;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;

public class Main extends Application {
    @Override
    public void start(Stage stage) {

        // data
        ObservableList<Crew> data = FXCollections.observableArrayList();
        data.addAll(new Crew(1, "A"), new Crew(2, "B"));

        // table
        TableColumn<Crew, Integer> crewIdCol = new TableColumn<Crew, Integer>("Crew ID");
        crewIdCol.setCellValueFactory(new PropertyValueFactory<Crew, Integer>("crewId"));
        crewIdCol.setMinWidth(120);
        TableColumn<Crew, String> crewNameCol = new TableColumn<Crew, String>("Crew Name");
        crewNameCol.setCellValueFactory(new PropertyValueFactory<Crew, String>("crewName"));
        crewNameCol.setMinWidth(180);
        TableView<Crew> table = new TableView<Crew>(data);
        table.getColumns().addAll(crewIdCol, crewNameCol);
        table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);

        // button
        Button button = new Button(" test ");
        button.setOnAction(ae -> {
            // test
            StringProperty nameProp = data.get(0).crewName();
            if(nameProp.get().equals("A")) {
                data.get(0).setCrewName("foo");
                // table.refresh();
                System.out.println("foo");
            } else {
                data.get(0).setCrewName("A");
                // table.refresh();
                System.out.println("A");
            }
        });

        VBox box = new VBox(10);
        box.setAlignment(Pos.CENTER);;
        box.getChildren().addAll(table, button); 
        Scene scene = new Scene(box);
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

}

Crew.java

package application;

import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class Crew {
    private final IntegerProperty crewId = new SimpleIntegerProperty();
    private final StringProperty crewName = new SimpleStringProperty();

    Crew(int id, String name) {
        crewId.set(id);
        crewName.set(name);
    }

    public IntegerProperty crewId() { return crewId; }
    public final int getCrewId() { return crewId.get(); }
    public final void setCrewId(int id) { crewId.set(id); }

    public StringProperty crewName() { return crewName; }
    public final String getCrewName() { return crewName.get(); }
    public final void setCrewName(String name) { crewName.set(name); }

}

1 个答案:

答案 0 :(得分:8)

您的模型类Crew有&#34;错误&#34;属性访问器方法的名称。如果不遵循推荐的方法命名方案,(有些遗留代码)PropertyValueFactory将无法找到属性,因此无法观察它们的变化:

package application;

import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class Crew {
    private final IntegerProperty crewId = new SimpleIntegerProperty();
    private final StringProperty crewName = new SimpleStringProperty();

    Crew(int id, String name) {
        crewId.set(id);
        crewName.set(name);
    }

    public IntegerProperty crewIdProperty() { return crewId; }
    public final int getCrewId() { return crewId.get(); }
    public final void setCrewId(int id) { crewId.set(id); }

    public StringProperty crewNameProperty() { return crewName; }
    public final String getCrewName() { return crewName.get(); }
    public final void setCrewName(String name) { crewName.set(name); }

}

或者,只需直接实现回调:

crewIdCol.setCellValueFactory(cellData -> cellData.getValue().crewIdProperty());

在这种情况下,编译器将确保您使用属性的现有方法名称。