5 Replies Latest reply: Aug 2, 2013 4:51 AM by Sinha_MCA RSS

    how to bind object hierarchy with TableView

    ti*422354*im
      Dear all,

      I have two classes Person and Contact, in which Contact is an aggregate with Person. How can I bind the property of the aggregate object with the TableView like:

      tableCol.setCellValueFactory(new PropertyValueFactory<Person, String>("*contact.name*"));


      public class Person {   
      private StringProperty name = new StringProperty("Unnamed");
      public String getName() { return name.get(); }
      public void setName(String value) { name.set(value); }
      public StringProperty nameProperty() { return name; }

      private ObjectProperty<Contact> contact = new SimpleObjectProperty<Contact>();
      public String getContact() { return contact.get(); }
      public ObjectProperty contactProperty() { return contact; }
      }

      public class Contact {
      private StringProperty name = new StringProperty("Unnamed");
      public String getName() { return name.get(); }
      public void setName(String value) { name.set(value); }
      public StringProperty nameProperty() { return name; }
      }

      Edited by: ti**** on 03.01.2013 12:44

      Edited by: ti**** on 03.01.2013 12:44

      Edited by: ti**** on 03.01.2013 12:44
        • 1. Re: how to bind object hierarchy with TableView
          James_D
          You need to implement the cell value factory yourself.

          I would advise making the Contact property of Person read only (i.e. change the return type of Person.getContact() to ReadOnlyObjectProperty), to prevent person.contactProperty().set(...). If you do that, the following will work:
          tableCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Person,String>, ObservableValue<String>>() {
            public ObservableValue<String> call(TableColumn.CellDataFeatures<Person,String> cellDataFeatures) {
              Person person = cellDataFeatures.getValue();
              Contact contact = person.getContact();
              return contact.nameProperty();
            }
          });
          Without that change, person.contactProperty().set(...) will change the data but not update the table (which is only observing the name property, not the contact property).

          Edited by: James_D on Jan 3, 2013 1:17 PM
          • 2. Re: how to bind object hierarchy with TableView
            ti*422354*im
            Thank you, it works (even it is a lot of code ;-) )

            Regards Tim
            • 3. Re: how to bind object hierarchy with TableView
              James_D
              Java 8 lambda expressions will significantly reduce the amount of code needed for this. I think (and I'm typing this on a phone, so not guaranteed to be accurate)
              tableCol.setCellValueFactory(
                features -> features.getValue().getContact().nameProperty()
              )
              • 4. Re: how to bind object hierarchy with TableView
                shakir.gusaroff
                Hi. How about this?
                import javafx.application.Application;
                import javafx.event.ActionEvent;
                import javafx.event.EventHandler;
                import javafx.scene.Scene;
                import javafx.scene.control.Button;
                import javafx.scene.layout.StackPane;
                import javafx.stage.Stage;
                
                import javafx.application.Application;
                
                import javafx.scene.Group;
                
                import javafx.scene.Scene;
                
                import javafx.stage.Stage;
                
                import javafx.beans.property.BooleanProperty;
                import javafx.beans.property.ObjectProperty;
                
                import javafx.beans.property.SimpleBooleanProperty;
                import javafx.beans.property.SimpleObjectProperty;
                
                import javafx.beans.property.StringProperty;
                
                import javafx.beans.property.SimpleStringProperty;
                
                import javafx.beans.value.ChangeListener;
                
                import javafx.beans.value.ObservableValue;
                
                import javafx.collections.FXCollections;
                
                import javafx.collections.ObservableList;
                
                import javafx.event.EventHandler;
                
                import javafx.geometry.Pos;
                
                import javafx.scene.control.CheckBox;
                
                import javafx.scene.control.TableCell;
                
                import javafx.scene.control.TableColumn;
                
                import javafx.scene.control.TableColumn.CellEditEvent;
                
                import javafx.scene.control.TableView;
                
                import javafx.scene.control.TextField;
                
                import javafx.scene.control.cell.PropertyValueFactory;
                
                import javafx.scene.input.KeyCode;
                
                import javafx.scene.input.KeyEvent;
                import javafx.scene.layout.VBox;
                
                import javafx.util.Callback;
                
                public class TableCellFactorySample2 extends Application {
                    
                    
                        final ObservableList<Person> data = FXCollections.observableArrayList(
                                new Person("Jacob", "Smith", "jacob.smith@example.com", new Contact("a")),
                                new Person("Isabella", "Johnson", "isabella.johnson@example.com", new Contact("b")),
                                new Person("Ethan", "Williams", "ethan.williams@example.com", new Contact("c")),
                                new Person("Emma", "Jones", "emma.jones@example.com", new Contact("d")),
                                new Person("Michael", "Brown", "michael.brown@example.com", new Contact("e")));
                    
                    
                
                    private void init(Stage primaryStage) {
                
                        Group root = new Group();
                
                        primaryStage.setScene(new Scene(root));
                
                
                
                        TableColumn firstNameCol = new TableColumn();
                
                        firstNameCol.setText("First");
                
                        firstNameCol.setCellValueFactory(new PropertyValueFactory("firstName"));
                
                        //"Last Name" column
                
                        TableColumn lastNameCol = new TableColumn();
                
                        lastNameCol.setText("Last");
                
                        lastNameCol.setCellValueFactory(new PropertyValueFactory("lastName"));
                
                
                        TableColumn emailCol = new TableColumn();
                        emailCol.setText("Email");
                        emailCol.setMinWidth(200);
                        emailCol.setCellValueFactory(new PropertyValueFactory("email"));
                
                
                
                        TableColumn contactCol = new TableColumn<Person, Contact>();
                        contactCol.setText("Contact");
                        contactCol.setMinWidth(50);
                        contactCol.setCellValueFactory(new PropertyValueFactory("contact"));
                
                
                
                        TableView tableView = new TableView();
                
                        tableView.setItems(data);
                
                        VBox vb = new VBox();
                
                        tableView.setEditable(true);
                
                        tableView.getColumns().addAll(firstNameCol, lastNameCol, emailCol, contactCol);
                
                
                
                        vb.getChildren().addAll(tableView);
                        root.getChildren().addAll(vb);
                
                    }
                
                    public static class Contact {
                
                        private StringProperty name = new SimpleStringProperty("Unnamed");
                
                        private Contact(String c) {
                
                            this.name = new SimpleStringProperty(c);
                
                        }
                
                        public String getName() {
                            return name.get();
                        }
                
                        public void setName(String value) {
                            name.set(value);
                        }
                
                        public StringProperty nameProperty() {
                            return name;
                        }
                
                        public String toString() {
                            return name.get();
                        }
                    }
                
                    //Person object
                    public static class Person {
                
                        private StringProperty firstName;
                        private StringProperty lastName;
                        private StringProperty email;
                        private ObjectProperty<Contact> contact;
                
                        private Person(String fName, String lName, String email, Contact c) {
                
                
                
                            this.firstName = new SimpleStringProperty(fName);
                
                            this.lastName = new SimpleStringProperty(lName);
                
                            this.email = new SimpleStringProperty(email);
                
                
                            this.contact = new SimpleObjectProperty(c);
                
                
                
                
                        }
                
                        public StringProperty firstNameProperty() {
                            return firstName;
                        }
                
                        public StringProperty lastNameProperty() {
                            return lastName;
                        }
                
                        public StringProperty emailProperty() {
                            return email;
                        }
                
                        public ObjectProperty<Contact> contactProperty() {
                            return contact;
                        }
                
                        public void setLastName(String lastName) {
                            this.lastName.set(lastName);
                        }
                
                        public void setFirstName(String firstName) {
                            this.firstName.set(firstName);
                        }
                
                        public void setEmail(String email) {
                            this.email.set(email);
                        }
                
                        public void setContact(Contact c) {
                            this.contact.set(c);
                        }
                    }
                
                    @Override
                    public void start(Stage primaryStage) throws Exception {
                
                        init(primaryStage);
                
                        primaryStage.show();
                        
                        data.add(new Person("Michael", "Brown", "michael.brown@example.com", new Contact("x")));
                
                    }
                
                    public static void main(String[] args) {
                        launch(args);
                    }
                }
                • 5. Re: how to bind object hierarchy with TableView
                  Sinha_MCA

                  Hello,

                   

                         The above solutions works fine for  once you know the object at compile time.

                   

                           My requirement is that

                           class College{

                           Student student;

                   

                           }

                   

                          Student{

                           String name;

                           }

                   

                         i want to bind to table view like this

                       TableColumn<College, String> col = new TableColumn<College,  String>("Name");

                              

                        col.setCellValueFactory(new PropertyValueFactory<College,  String>("student.name");

                   

                        it doesn't seems to be working,because  it try to find property with the name "student.name" which is not available.

                   

                      

                   

                    further i would like to modify code like this

                   

                         TableColumn<T, String> col = new TableColumn<T,  String>("Name");

                              

                         col.setCellValueFactory(new PropertyValueFactory<T,  String>("student.name");

                   

                   

                  so my requirement is that  it should call getStudent().getName() and return the name value.

                  since we are setting like  as follows.

                  col.setCellValueFactory(new PropertyValueFactory<College,  String>("student.name");

                   

                  how we can implement this logic???

                   

                  thanks