Javafx tableview not showing data in all columns

32,171

This question is really a duplicate of: Javafx PropertyValueFactory not populating Tableview, but I'll specifically address your specific case, so it's clear.

Suggested solution (use a Lambda, not a PropertyValueFactory)

Instead of:

aColumn.setCellValueFactory(new PropertyValueFactory<Appointment,LocalDate>("date"));

Write:

aColumn.setCellValueFactory(cellData -> cellData.getValue().dateProperty());

For more information, see this answer:


Solution using PropertyValueFactory

The lambda solution outlined above is preferred, but if you wish to use PropertyValueFactory, this alternate solution provides information on that.

Background

PropertyValueFactory uses reflection to determine the methods to get and set data values as well as to retrieve bindable properties from your model class. The pattern followed is:

PropertyValueType getName()
void setName(PropertyValueType value)
PropertyType nameProperty()

Where "name" is the string specified in the PropertyValueFactory constructor. The first letter of the property name in the getter and setter is capitalized (by java bean naming convention).

Why your application doesn't work

You have these three expressions:

new PropertyValueFactory<sresult, String>("DateEntered")
new PropertyValueFactory<sresult, String>("cDesc")
new PropertyValueFactory<sresult, String>("CreatedBy")

For your sample properties, the PropertyValueFactory will look for these methods:

"DateEntered" => getDateEntered()
"cDesc" => getCDesc()
"CreatedBy" => getCreatedBy()

And you have these three getters on your sresult class:

getDateEntered()
getcDesc()
getEnteredBy()

Only getDateEntered() is going to be picked up by the PropertyValueFactory because that is the only matching method defined in the sresult class.

Advice

You will have to adopt Java standards if you want the reflection in PropertyValueFactory to work (the alternative is to not use the PropertyValueFactory and instead write your own cell factories from scratch).

Adopting Java camel case naming conventions also makes it easier for Java developers to read your code.

Share:
32,171

Related videos on Youtube

kmitchell.dev
Author by

kmitchell.dev

Updated on December 29, 2021

Comments

  • kmitchell.dev
    kmitchell.dev over 2 years

    OK, new to java by several weeks, but have been programming for 30 years. The following code executes, but only the first column is showing anything. The data object is showing multiple rows of data, with fields of data that are filled in. I'm sure I'm missing something, and have looked through similar questions on here.

    APVoucher_batchgridController.java

    import java.net.URL;
    import java.util.ResourceBundle;
    import javafx.event.ActionEvent;
    import javafx.fxml.Initializable;
    import javafx.fxml.FXML;
    import javafx.scene.control.TableView;
    import javafx.scene.input.MouseEvent;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.scene.control.TableColumn;
    import javafx.scene.control.cell.PropertyValueFactory;
    
    /**
     * FXML Controller class
     *
     * @author kmitchell
     */
    public class APVoucher_batchgridController implements Initializable {
    
        public TableView tblMainList;
        public TableColumn colDateEntered;
        public TableColumn colCreatedBy;
        public TableColumn colDescription;
    
        /**
         * Initializes the controller class.
         */
        @Override
        public void initialize(URL url, ResourceBundle rb) {
    
        }
    
        @FXML
        public void opentables(ActionEvent event) {
    
            Object forName = null;
            Connection conn = null;
            Statement stmt = null;
    
            ResultSet rs = null;
    
            colDateEntered.setCellValueFactory(new PropertyValueFactory<sresult, String>("DateEntered"));
    
            colDescription.setCellValueFactory(new PropertyValueFactory<sresult, String>("cDesc"));
    
            colCreatedBy.setCellValueFactory(new PropertyValueFactory<sresult, String>("CreatedBy"));
    
            try {
                // load the driver into memory
                forName = Class.forName("jstels.jdbc.dbf.DBFDriver2");
    
            } catch (ClassNotFoundException ex) {
                Logger.getLogger(APVoucher_batchgridController.class.getName()).log(Level.SEVERE, null, ex);
            }
    
            try {
                conn = DriverManager.getConnection("jdbc:jstels:dbf:e:\\keystone-data\\keyfund\\seymour\\keyfund.dbc");
            } catch (SQLException ex) {
                Logger.getLogger(APVoucher_batchgridController.class.getName()).log(Level.SEVERE, null, ex);
            }
    
            if (conn != null) {
                try {
                    stmt = conn.createStatement();
                } catch (SQLException ex) {
                    Logger.getLogger(APVoucher_batchgridController.class.getName()).log(Level.SEVERE, null, ex);
                }
    
                if (stmt != null) {
    
                    // execute a query
                    try {
                        ObservableList<Object> data = FXCollections.observableArrayList();
    
                        rs = stmt.executeQuery("SELECT denteredon, cdesc, ccreatedby FROM apvbatch WHERE ldeleted = false ORDER BY denteredon DESC");
    
                        while (rs.next()) {
    
                            String enteredon = rs.getString("denteredon");
                            String desc = rs.getString("cdesc");
                            String createdby = rs.getString("ccreatedby");
    
                            sresult row = new sresult(createdby, enteredon, desc);
    
                            data.add(row);
                        }
    
                        tblMainList.setItems(data);
    
                        tblMainList.setVisible(true);
    
    
                    } catch (SQLException ex) {
                        Logger.getLogger(APVoucher_batchgridController.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        }
    
        public class sresult {
    
            private String DateEntered;
            private String EnteredBy;
            private String cDesc;
    
            public sresult(String T, String d, String c) {
                this.EnteredBy = T;
                this.DateEntered = d;
                this.cDesc = c;
            }
    
            public String getEnteredBy() {
                return EnteredBy;
            }
    
            public void setEnteredBy(String T) {
                EnteredBy = T;
            }
    
            public String getDateEntered() {
                return DateEntered;
            }
    
            public void setDateEntered(String d) {
                DateEntered = d;
            }
    
            public String getcDesc() {
                return cDesc;
            }
    
            public void setcDesc(String c) {
                cDesc = c;
            }
        }
    }
    

    and APVoucher_batchgrid.fxml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import java.lang.*?>
    <?import java.net.*?>
    <?import java.util.*?>
    <?import javafx.geometry.*?>
    <?import javafx.scene.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.*?>
    <?import javafx.scene.text.*?>
    
    <AnchorPane id="AnchorPane" fx:id="batchlistform" prefHeight="400.0" prefWidth="600.0" styleClass="mainFxmlClass" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="keystone.APVoucher_batchgridController">
      <children>
        <BorderPane layoutX="0.0" layoutY="0.0" prefHeight="400.0" prefWidth="600.0">
          <center>
            <AnchorPane prefHeight="-1.0" prefWidth="-1.0">
              <children>
                <Pane layoutX="0.0" layoutY="0.0" prefHeight="53.0" prefWidth="580.0">
                  <children>
                    <Label layoutX="7.0" layoutY="9.0" prefWidth="202.0" text="AP Vouchers Batch List">
                      <font>
                        <Font name="System Bold" size="14.0" />
                      </font>
                    </Label>
                    <Button fx:id="btnClose" cancelButton="true" layoutX="513.0" layoutY="27.0" mnemonicParsing="false" text="Close" />
                    <Button id="btnClose" fx:id="apvRefresh" cancelButton="true" layoutX="185.0" layoutY="27.0" mnemonicParsing="false" onAction="#opentables" text="Refresh" />
                  </children>
                </Pane>
                <TableView fx:id="tblMainList" layoutX="0.0" layoutY="53.0" prefHeight="323.0" prefWidth="580.0">
                  <columns>
                    <TableColumn maxWidth="5000.0" minWidth="10.0" prefWidth="91.0" text="Date Entered" fx:id="colDateEntered" />
                    <TableColumn maxWidth="5000.0" minWidth="10.0" prefWidth="100.0" text="Created By" fx:id="colCreatedBy" />
                    <TableColumn maxWidth="5000.0" minWidth="10.0" prefWidth="261.0" text="Description" fx:id="colDescription" />
                  </columns>
                </TableView>
              </children>
            </AnchorPane>
          </center>
          <padding>
            <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
          </padding>
        </BorderPane>
      </children>
      <stylesheets>
        <URL value="@apvoucher_batchgrid.css" />
      </stylesheets>
    </AnchorPane>
    

    THANK YOU for the answer. Way to many years in case insensitive languages. This has been a quick and dirty exercise for me to learn java and the latest & greatest stuff or as I like to say New Exciting Technology (NExT!)

    For anyone looking at the answer and still not completely clued in, here are the changes that made the code work properly.

    colDateEntered.setCellValueFactory(new PropertyValueFactory<sresult, String>("Denteredon"));
    colDescription.setCellValueFactory(new PropertyValueFactory<sresult, String>("CDesc"));
    colEnteredBy.setCellValueFactory(new PropertyValueFactory<sresult, String>("Ccreatedby"));
    
    
        public class sresult {
    
            private String Denteredon;
            private String Ccreatedby;
            private String CDesc;
    
            public sresult(String T, String d, String c) {
                this.Ccreatedby = T;
                this.Denteredon = d;
                this.CDesc = c;
            }
    
            public String getCcreatedby() {
                return Ccreatedby;
            }
    
            public void setCreatedby(String T) {
                Ccreatedby = T;
            }
    
            public String getDenteredon() {
                return Denteredon;
            }
    
            public void setDenteredon(String d) {
                Denteredon = d;
            }
    
            public String getCDesc() {
                return CDesc;
            }
    
            public void setCDesc(String c) {
                CDesc = c;
            }
        }
    }
    
  • Osama Al-Banna
    Osama Al-Banna about 7 years
    @jewelsea can you explain how to create my cell factories ? this my question and I'm struggling here since a week stackoverflow.com/questions/43099841/… the program run without an error and does not show up the data in the table !!
  • kleopatra
    kleopatra over 6 years
    not entirely certain what you mean - but there's no need for a "final" modifier ..
  • trilogy
    trilogy over 5 years
    You don't have to create your own cell value factories, just set the col.setCellValueFactory(features -> features.getValue().colProperty()); if your properties are exposed by the model class.
  • Gary
    Gary over 4 years
    Final isn't required, but he raises a good point about the getters needing to be public.
  • kleopatra
    kleopatra about 3 years
    no: column names have nothing to do with it - it's the property name that matters .. please read the api doc of PropertyValueFactory. It's good you try to answer but: be precise, format the code and stick to java naming conventions.

Related