1

I am trying to implements the following JavaFX vs Spring implementation, but cannot grasp how to operate and display entity in TableView form. (I means Gender class. This is just an entity, that represented table, which can include only two value: male or female - and I want display this value in TableView)

Person:

@Entity
@Table(name = "passport_data")
public class Person {

  @Id
  @Column(name = "id")
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private long id;

  @Column(name = "ipn", unique = true)
  private long ipn;

  @One_to_One
  private Gender gender;
//getters & setters
}

Gender

  @Entity
  @Table(name = "gender")

public class Gender {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(name = "gender")
    String gender;
//getters & setters
}

In MainController class I am implement TableView<> for data imaging and editing table:

Controller:

public class MainController {

    @FXML private TableView<Person> table;

    @FXML private TextField ipnTxt; //Long data in Person entity
    @FXML private TextField genderTxt; //Other entity (Gender) in Person entity

private ObservableList<Person> data;

@PostConstruct
public void init(){
    List<Person> personList = personService.getAllPerson();
    data = FXCollections.observableArrayList(personList);

    TableColumn<Person, String> ipnColumn = new TableColumn<>("IPN");
    ipnColumn.setCellValueFactory(new PropertyValueFactory<>("ipn"));

    TableColumn<Person, String> genderColumn = new TableColumn<>("Gender");
    genderColumn.setCellValueFactory(new PropertyValueFactory<>("gender"));

    table.getColumns().setAll(ipnColumn, genderColumn);
    table.setItems(data);
}

.fxml file *Part, where execute table displaying:

<TableView fx:id="table" editable="true" prefHeight="200.0" prefWidth="405.0" tableMenuButtonVisible="true" AnchorPane.bottomAnchor="50.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
            <columnResizePolicy><TableView fx:constant="CONSTRAINED_RESIZE_POLICY" /></columnResizePolicy>
        </TableView>
        <HBox alignment="CENTER" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0">
            <children>
                <!--<TextField fx:id="id" promptText="ID">-->
                    <!--<HBox.margin>-->
                        <!--<Insets right="3.0"/>-->
                    <!--</HBox.margin>-->
                <!--</TextField>-->
                <TextField fx:id="ipnTxt" promptText="IPN">
                    <HBox.margin>
                        <Insets right="3.0"/>
                    </HBox.margin>
                </TextField>
                <TextField fx:id="genderTxt" promptText="Gender">
                    <HBox.margin>
                        <Insets right="3.0"/>
                    </HBox.margin>
                </TextField>
                <Button minWidth="-Infinity" mnemonicParsing="false" onAction="#addPerson" text="Add" />
            </children>
        </HBox>

So, in result I have data from IPN column and reference on Gender object in gender column:

enter image description here

But I need to get String gender value from those objects. How to get and put value from object in this case?

Additional info

Full Person class

package com.production.weighlifting.weightliftingviewer.model.domain;

import javax.persistence.*;
import java.sql.Date;

@Entity
@Table(name = "passport_data")
public class Person {

  @Id
  @Column(name = "id")
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private long id;

  @Column(name = "ipn", unique = true)
  private long ipn;

  @Column(name = "passport_number", unique = true)
  private String passportNumber;

  @Column(name = "name")
  private String name;

  @Column(name = "last_name")
  private String lastName;

  @Column(name = "born")
  private java.sql.Date born;

  public String genderValue;

  @OneToOne
//  @Column(name = "gender_id")
  private Gender gender;

  public Person(){

  }

  public Person(long ipn, String passportNumber, String name, String lastName, Date born, Gender gender) {
    this.ipn = ipn;
    this.passportNumber = passportNumber;
    this.name = name;
    this.lastName = lastName;
    this.born = born;
    this.gender = gender;
    this.genderValue = gender.getGender();
  }

  public long getId() {
    return id;
  }

  public void setId(long id) {
    this.id = id;
  }


  public long getIpn() {
    return ipn;
  }

  public void setIpn(long ipn) {
    this.ipn = ipn;
  }


  public String getPassportNumber() {
    return passportNumber;
  }

  public void setPassportNumber(String passportNumber) {
    this.passportNumber = passportNumber;
  }


  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }


  public String getLastName() {
    return lastName;
  }

  public void setLastName(String lastName) {
    this.lastName = lastName;
  }


  public java.sql.Date getBorn() {
    return born;
  }

  public void setBorn(java.sql.Date born) {
    this.born = born;
  }

  public Gender getGender() {
    return gender;
  }

  public void setGender(Gender gender) {
    this.gender = gender;
  }

  public String getGenderValue(){return genderValue;}
}

Full Gender class

@Entity
@Table(name = "gender")
public class Gender {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(name = "gender")
    private String gender;

    public Gender(){

    }

    public long getId() {
        return id;
    }

    public Gender(GenderEnum genderEnum) {
        this.gender = genderEnum.name();
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }
}

2 Answers 2

1

Simply implement the cellValueFactory on your own:

TableColumn<Person, String> genderColumn = new TableColumn<>("Gender");
// genderColumn.setCellValueFactory(new PropertyValueFactory<>("gender"));
genderColumn.setCellValueFactory(cd -> new SimpleStringProperty(cd.getValue().getGender().getGender()));

Alternatively you could use the cellFactory to customize how a Gender object is displayed:

public class GenderTableCell<T> extends TableCell<T, Gender> {
    @Override
    protected void updateItem(Gender item, boolean empty) {
        super.updateItem(item, empty);
        setText(empty || item == null ? "" : item.getGender());
    }
}

You could use the updateItem method instead to e.g. update a ImageView used as TableCell.graphic to display gender symbols instead...

TableColumn<Person, Gender> genderColumn = new TableColumn<>("Gender");
genderColumn.setCellValueFactory(new PropertyValueFactory<>("gender"));
genderColumn.setCellFactory(col -> new GenderTableCell<>());
Sign up to request clarification or add additional context in comments.

Comments

1

You are trying to display nested value. JavaFx does not provide explicit nested values handling like "person.gender". You need to add getter method to Person which will act as Gender String provider. Btw - although it works, using PropertyValueFactory is not the best choice.

public class Gender {

    private String value;

    public Gender(String value) {
        this.value = value;
    }

    public String getGender() {
        return value;
    }
}

public class Person {

    private String name;
    private Gender gender;

    public Person(String name, Gender gender) {
        this.name = name;
        this.gender = gender;
    }

    public String getName() {
        return name;
    }

    public Gender getGender() {
        return gender;
    }

    public String getGenderValue() {
        return gender.getGender();
    }
}

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;

public class NestedPropertyApp extends Application {

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

    @Override
    public void start(Stage stage) throws Exception {

        ObservableList<Person> persons = FXCollections.observableArrayList();
        persons.add(new Person("Peter", new Gender("Male")));

        TableView<Person> tableView = new TableView<>(persons);

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

        TableColumn<Person, String> genderColumn = new TableColumn<>("Gender");
        genderColumn.setCellValueFactory(new PropertyValueFactory<>("genderValue"));

        tableView.getColumns().add(nameColumn);
        tableView.getColumns().add(genderColumn);

        stage.setScene(new Scene(tableView));
        stage.show();
    }
}

3 Comments

Thanks, but it is not work for me(. I even create String genderValue field, that initialize in constructor, and all works well, but in table nothing not disblay in Gender column
Please paste your getters from Person class. Or maybe even the whole Person class.
Done! I think, that caus in private ObservableList<Person> data; string. So, I am should be try to create one more class, that will by dublicate the Person class and to be using only for display data to table.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.