JavaFX将表格中的ComboBox值绑定到模型,每行具有不同的选项

时间:2019-05-08 07:39:32

标签: java javafx combobox

我们要在表中创建一个组合框。每个组合框应基于行具有不同的选项。在我们的示例中,我们有一个具有不同服务器IP地址的表,以及一个包含该服务器上所有用户的组合框。

我们不知道如何在CellFactory内的组合框中填充不同的选项,而且我们不确定如何将comboxbox条目与相应的模型绑定。

我们创建了一个示例,也许有人有主意:

凭据模型

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

public class CredentialModel {

    private StringProperty username = new SimpleStringProperty();

    private StringProperty password = new SimpleStringProperty();

    public CredentialModel(String username, String password) {
        setUsername(username);
        setPassword(password);
    }

    public String getUsername() {
        return username.get();
    }

    public StringProperty usernameProperty() {
        return username;
    }

    public void setUsername(String username) {
        this.username.set(username);
    }

    public String getPassword() {
        return password.get();
    }

    public StringProperty passwordProperty() {
        return password;
    }

    public void setPassword(String password) {
        this.password.set(password);
    }
}

ServerModel

import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

public class ServerModel {

    private IntegerProperty id = new SimpleIntegerProperty();


    private StringProperty ip = new SimpleStringProperty();

    private ObjectProperty<CredentialModel> credential = new SimpleObjectProperty<>();

    private ObservableList<CredentialModel> allCredentials = FXCollections.observableArrayList();

    public ObservableList<CredentialModel> getAllCredentials() {
        return allCredentials;
    }

    public void setAllCredentials(ObservableList<CredentialModel> allCredentials) {
        this.allCredentials = allCredentials;
    }

    public ServerModel(Integer id, String ip) {
        setId(id);
        setIp(ip);
    }

    public String getIp() {
        return ip.get();
    }

    public StringProperty ipProperty() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip.set(ip);
    }

    public CredentialModel getCredential() {
        return credential.get();
    }

    public ObjectProperty<CredentialModel> credentialProperty() {
        return credential;
    }

    public void setCredential(CredentialModel credential) {
        this.credential.set(credential);
    }

    public int getId() {
        return id.get();
    }

    public IntegerProperty idProperty() {
        return id;
    }

    public void setId(int id) {
        this.id.set(id);
    }

}

主应用程序 TableApplication

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;

public class TableApplication extends Application {

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

    @Override
    public void start(Stage primaryStage) throws Exception {
        VBox box = new VBox();

        TableView<ServerModel> tableView = new TableView<>();
        TableColumn<ServerModel, String> ipColumn = new TableColumn<>("IP-Address");
        TableColumn<ServerModel, CredentialModel> userColumn = new TableColumn<>("Username");
        tableView.getColumns().addAll(ipColumn, userColumn);

        ipColumn.setCellValueFactory(param -> param.getValue().ipProperty());

        tableView.getItems().addAll(populateTable());

        userColumn.setCellFactory(new Callback<TableColumn<ServerModel,CredentialModel>, TableCell<ServerModel,CredentialModel>>() {
            @Override
            public TableCell<ServerModel, CredentialModel> call(TableColumn<ServerModel, CredentialModel> param) {
                return new UserComboBoxTableCell();
            }
        });

        Button button = new Button("Start");
        button.setOnAction(event -> System.out.println(tableView.getSelectionModel().getSelectedItem().getCredential().getUsername()));
        box.getChildren().addAll(tableView, button);

        Scene scene = new Scene(box,800, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private ObservableList<ServerModel> populateTable() {

        ServerModel serverModel1 = new ServerModel(1, "192.168.0.1");
        serverModel1.setAllCredentials(FXCollections.observableArrayList(new CredentialModel("user1", "pw1"), new CredentialModel("user2", "pw2")));

        ServerModel serverModel2 = new ServerModel(2, "192.168.0.2");
        serverModel2.setAllCredentials(FXCollections.observableArrayList(new CredentialModel("user3", "pw3")));

        return FXCollections.observableArrayList(serverModel1, serverModel2);
    }

和TableCellClass UserComboBoxTableCell

import javafx.scene.control.ComboBox;
import javafx.scene.control.TableCell;

public class UserComboBoxTableCell extends TableCell<ServerModel, CredentialModel> {

    public UserComboBoxTableCell() {

    }

    @Override
    protected void updateItem(CredentialModel item, boolean empty) {
        super.updateItem(item, empty);

        if(empty == false) {
            if(getTableRow() != null && getTableView() != null) {
                int index = getTableRow().getIndex();
                ServerModel serverModel = getTableView().getItems().get(index);

                ComboBox<CredentialModel> box = new ComboBox<>(serverModel.getAllCredentials());
                box.valueProperty().bindBidirectional(serverModel.credentialProperty());
                setGraphic(box);
            }
        }
    }
}

方法 loadCredentials 的想法是,对于每一行,应为“虚拟”调用此方法-为服务器行加载凭据。

该按钮的 onAction 方法的想法是显示所选服务器行中的所选用户名。目前,我们仅打印ip地址,因为凭据始终为null(因为此刻未绑定)。

感谢您的帮助。 豪克

编辑 我只是向服务器添加了一个可观察的凭证模型列表,并以不同的方式填充了列表视图。但是我仍然不确定如何在CellFactory中为组合框设置选项,因为我需要访问该行,并且不确定绑定。

EDIT2 现在正在工作。我更新了上面的示例。

0 个答案:

没有答案