JavaFX tableview填充动态创建的嵌套列中的值

时间:2016-07-17 12:40:34

标签: javafx tableview

我在我们的一个javaFX应用程序中遇到JAVAFX tableview中的一点。我使用一个表视图来显示一些数据。在该tableView中,其中一列具有嵌套列。我从列表中创建的这些嵌套列。现在我在这里举一个例子。现在我在tableView中有两列。姓名和技能。技能组列下面有两个嵌套列。我正在从nestedColumnsNameList读取嵌套列名。我试图从列表skillList填充这些嵌套列中的值,该列表有两个值[Java,Dot Net]。现在,每当我尝试从skillList中填充这些嵌套列中的值时,对于每一行,我在每个嵌套列中获得与Dot Net相同的值。以下是我的代码:

    package demo.tableView;


import java.util.ArrayList;
import java.util.List;

import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Spinner;
import javafx.scene.control.SpinnerValueFactory;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class UpdateTableViewDynamicColumns extends Application {

    private TextField firtNameField = new TextField();
    private TextField lastNameField = new TextField();
    private TextField emailField = new TextField();
    private TextField speedField = new TextField();
    private TextField stopspeedField = new TextField();
    private Stage editView;
    private Person fPerson;
    TableView<Person> table = new TableView<Person>();;
    public static class Person {

       private String name;
        private String skillset;
        private String skills;
        /**
         * @return the firstName

        /**
         * @return the skills
         */
        public String getSkills() {
            return skills;
        }
        /**
         * @param skills the skills to set
         */
        public void setSkills(String skills) {
            this.skills = skills;
        }
        /**
         * @return the skillset
         */
        public String getSkillset() {
            return skillset;
        }
        /**
         * @param skillset the skillset to set
         */
        public void setSkillset(String skillset) {
            this.skillset = skillset;
        }
        /**
         * @return the name
         */
        public String getName() {
            return name;
        }
        /**
         * @param name the name to set
         */
        public void setName(String name) {
            this.name = name;
        }


  }

    private final ObservableList<Person> data =
            FXCollections.observableArrayList();

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

    @Override
    public void start(Stage stage) {
        Scene scene = new Scene(new Group());
        stage.setTitle("Table View Sample");
        stage.setWidth(535);
        stage.setHeight(535);
        editView = new Stage();

        final Label label = new Label("Address Book");
        label.setFont(new Font("Arial", 20));

        TableColumn firstNameCol = new TableColumn("Name");
        firstNameCol.setCellValueFactory(
                new PropertyValueFactory<Person, String>("name"));
        firstNameCol.setMinWidth(150);


        /*
         * this list contains the names of nested columns
         */
        List<String> nestedColumnsNameList = new ArrayList<String>();
        nestedColumnsNameList.add("Skill 1");
        nestedColumnsNameList.add("Skill 2");


        TableColumn skillSetCol = new TableColumn("Skillset");
        skillSetCol.setMinWidth(200);
        skillSetCol.setCellValueFactory(new PropertyValueFactory<Person, String>("skillset"));


        for(int i=0;i<nestedColumnsNameList.size();i++){
            TableColumn ageValCol = new TableColumn(nestedColumnsNameList.get(i));
            ageValCol.setCellValueFactory(new PropertyValueFactory<Person, String>("skills"));
            skillSetCol.getColumns().add(ageValCol);
        }

        int count = 3;

        List<String> nameList = new ArrayList<String>();
        nameList.add("Ajit Patil");
        nameList.add("Ketan Mehta");
        nameList.add("Jacob George");

        /*
         * the below list values will be set in skill columns skill1 , skill2 
         */
        List<String> skillList = new ArrayList<String>();
        skillList.add("Java");
        skillList.add("Dot net");

       for(int i=0; i<nameList.size(); i++){
            Person p =  new Person();
            p.setName(nameList.get(i));

            for(int x=0; x<skillList.size();x++){
                p.setSkills(skillList.get(x));
            }
            data.add(p);
        }
        table.setItems(data);
        table.getColumns().addAll(firstNameCol, skillSetCol);
//--- create a edit button and a editPane to edit person   
        Button addButton = new Button("Add");
        addButton.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                fPerson = null;
                firtNameField.setText("");
                lastNameField.setText("");
                emailField.setText("");
                editView.show();
            }
        });
        Button editButton = new Button("Edit");
        editButton.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                /*if (table.getSelectionModel().getSelectedItem() != null) {
                    fPerson = table.getSelectionModel().getSelectedItem();
                    firtNameField.setText(fPerson.getFirstName());
                    lastNameField.setText(fPerson.getLastName());
                    emailField.setText(fPerson.getEmail());
                    editView.show();
                }*/
            }
        });
        Button deleteButton = new Button("Delete");
        deleteButton.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                if (table.getSelectionModel().getSelectedItem() != null) {
                    data.remove(table.getSelectionModel().getSelectedItem());
                }
            }
        });
        Button setButton = new Button("Set");
        setButton.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {

                Stage primaryStage = new Stage();
                Spinner<Double> dspinner = new Spinner<>();
                dspinner.setValueFactory(new SpinnerValueFactory.DoubleSpinnerValueFactory(0.0, Double.MAX_VALUE, 0.0, 1));
                dspinner.setMaxWidth(60);
                Button setButton = new Button("Set");
                setButton.setMinWidth(50);
                GridPane grid = new GridPane();
                grid.setHgap(10);
                grid.setVgap(10);
                grid.setPadding(new Insets(10));

                grid.add(new Label("Set default speed [knots] : "), 0, 1);
                grid.add(dspinner, 1, 1);
                grid.add(setButton, 2, 1);

                Scene scene = new Scene(grid, 300, 80);
                primaryStage.setTitle("Set Default value for speed");
                primaryStage.setScene(scene);
                primaryStage.initModality(Modality.APPLICATION_MODAL);
                primaryStage.show();

                setButton.setOnAction(new EventHandler<ActionEvent>() {
                    @Override
                    public void handle(ActionEvent actionEvent) {
                        try {
                            setDefaultSpeed(dspinner);
                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }

                    private void setDefaultSpeed(Spinner<Double> dspinner) {
                        // TODO Auto-generated method stub

                    }
                });


            }
        });
        HBox addEditDeleteButtonBox = new HBox();
        addEditDeleteButtonBox.getChildren().addAll(addButton, editButton, deleteButton,setButton);
        addEditDeleteButtonBox.setAlignment(Pos.CENTER_RIGHT);
        addEditDeleteButtonBox.setSpacing(3);

        GridPane editPane = new GridPane();
        editPane.getStyleClass().add("editView");
        editPane.setPadding(new Insets(3));
        editPane.setHgap(5);
        editPane.setVgap(5);
        Label personLbl = new Label("Person:");
        editPane.add(personLbl, 0, 1);
        GridPane.setHalignment(personLbl, HPos.LEFT);

        firtNameField.setPrefWidth(250);
        lastNameField.setPrefWidth(250);
        emailField.setPrefWidth(250);
        Label firstNameLabel = new Label("First Name:");
        Label lastNameLabel = new Label("Last Name:");
        Label emailLabel = new Label("Email:");
        Label speedLabel = new Label("Start Speed:");
        Label speedLabel1 = new Label("stop Speed:");
        editPane.add(firstNameLabel, 0, 3);
        editPane.add(firtNameField, 1, 3);
        editPane.add(lastNameLabel, 0, 4);
        editPane.add(lastNameField, 1, 4);
        editPane.add(emailLabel, 0, 5);
        editPane.add(emailField, 1, 5);
        editPane.add(speedLabel, 0, 6);
        editPane.add(speedField, 1, 6);
        editPane.add(speedLabel1, 0, 7);
        editPane.add(stopspeedField, 1, 7);
        GridPane.setHalignment(firstNameLabel, HPos.RIGHT);
        GridPane.setHalignment(lastNameLabel, HPos.RIGHT);
        GridPane.setHalignment(emailLabel, HPos.RIGHT);
        GridPane.setHalignment(speedLabel, HPos.RIGHT);

        Button saveButton = new Button("Save");
        saveButton.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                if (fPerson == null) {
                    fPerson = new Person(
                            /*firtNameField.getText(),
                            lastNameField.getText(),
                            emailField.getText(),Double.parseDouble(speedField.getText()),Double.parseDouble(stopspeedField.getText()),""*/);
                    data.add(fPerson);
                } else {
                    int k = -1;
                    if (data.size() > 0) {
                        for (int i = 0; i < data.size(); i++) {
                            if (data.get(i) == fPerson) {
                                k = i;
                            }
                        }
                    }
                    fPerson.setName(firtNameField.getText());
                    data.set(k, fPerson);
                    table.setItems(data);

//  The following will work, but edited person has to be added to the button
//
//                    data.remove(fPerson);
//                    data.add(fPerson);

// add and remove refresh the table, but now move edited person to original spot, 
// it failed again with the following code
//                    while (data.indexOf(fPerson) != k) {
//                        int i = data.indexOf(fPerson);
//                        Collections.swap(data, i, i - 1);
//                    }
                }
                editView.close();
            }
        });
        Button cancelButton = new Button("Cancel");
        cancelButton.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                editView.close();
            }
        });
        TitledBorder b = new TitledBorder();
        HBox saveCancelButtonBox = new HBox();
        saveCancelButtonBox.getChildren().addAll(saveButton, cancelButton);
        saveCancelButtonBox.setAlignment(Pos.CENTER_RIGHT);
        saveCancelButtonBox.setSpacing(3);

//        saveCancelButtonBox.setBorder( new Border(new BorderStroke(Color.BLUE, BorderStrokeStyle.SOLID, null, new BorderWidths(3))));
        VBox editBox = new VBox();
        editBox.getChildren().addAll(editPane, saveCancelButtonBox);

        Scene editScene = new Scene(editBox);
        editView.setTitle("Person");
        editView.initStyle(StageStyle.UTILITY);
        editView.initModality(Modality.APPLICATION_MODAL);
        editView.setScene(editScene);
        editView.close();

        final VBox vbox = new VBox();
        vbox.setSpacing(5);
        vbox.getChildren().addAll(label, table, addEditDeleteButtonBox);
        vbox.setPadding(new Insets(10, 0, 0, 10));

        ((Group) scene.getRoot()).getChildren().addAll(vbox);

        stage.setScene(scene);
        stage.show();
    }
}

这是我的输出: enter image description here

我想填补不同的价值 - &gt;技能1和技能2专栏中的java和dot net。请帮助。

1 个答案:

答案 0 :(得分:1)

您想要使用多个值。因此,您无法将元素存储在单个String字段中(至少不是以方便的方式)。您需要使用支持多个值的数据类型,例如List<String>PropertyValueFactory无法处理此类型,因此您需要使用自定义cellValueFactory

public static class Person {
    ...
    private final List<String> skills = new ArrayList<>();

    public List<String> getSkills() {
        return skills;
    }

    ...
}

创建列

for (int i = 0; i < nestedColumnsNameList.size(); i++) {
    final int index = i;
    TableColumn<Person, String> ageValCol = new TableColumn<>(nestedColumnsNameList.get(i));

    // get data from list using index
    ageValCol.setCellValueFactory(cellData -> Bindings.createObjectBinding(() -> cellData.getValue().getSkills().get(index)));

    skillSetCol.getColumns().add(ageValCol);
}

项目创建

for (int i = 0; i < nameList.size(); i++) {
    Person p = new Person();
    p.setName(nameList.get(i));

    p.getSkills().addAll(skillList);

    data.add(p);
}