Javafx PropertyValueFactory not populating Tableview

Nepze Tyson picture Nepze Tyson · Jun 11, 2013 · Viewed 17.5k times · Source

This has baffled me for a while now and I cannot seem to get the grasp of it. I'm using Cell Value Factory to populate a simple one column table and it does not populate in the table.

It does and I click the rows that are populated but I do not see any values in them- in this case String values. [I just edited this to make it clearer]

I have a different project under which it works under the same kind of data model. What am I doing wrong?

Here's the code. The commented code at the end seems to work though. I've checked to see if the usual mistakes- creating a new column instance or a new tableview instance, are there. Nothing. Please help!


//Simple Data Model Stock.java

public class Stock {

    private SimpleStringProperty stockTicker;

    public Stock(String stockTicker) {
        this.stockTicker = new SimpleStringProperty(stockTicker);
    }

    public String getstockTicker() {
        return stockTicker.get();
    }

    public void setstockTicker(String stockticker) {
        stockTicker.set(stockticker);
    }
}

//Controller class MainGuiController.java

    private ObservableList<Stock> data;
    @FXML
    private TableView<Stock> stockTableView;// = new TableView<>(data);
    @FXML
    private TableColumn<Stock, String> tickerCol;


    private void setTickersToCol() {
    try {
        Statement stmt = conn.createStatement();//conn is defined and works
        ResultSet rsltset = stmt.executeQuery("SELECT ticker FROM tickerlist order by ticker");
        data = FXCollections.observableArrayList();
        Stock stockInstance;
        while (rsltset.next()) {
            stockInstance = new Stock(rsltset.getString(1).toUpperCase());
            data.add(stockInstance);
        }
    } catch (SQLException ex) {
        Logger.getLogger(WriteToFile.class.getName()).log(Level.SEVERE, null, ex);
        System.out.println("Connection Failed! Check output console");
    }

    tickerCol.setCellValueFactory(new PropertyValueFactory<Stock,String>("stockTicker"));
    stockTableView.setItems(data);
    }

    /*THIS, ON THE OTHER HAND, WORKS*/
    /*Callback<CellDataFeatures<Stock, String>, ObservableValue<String>> cellDataFeat =
            new Callback<CellDataFeatures<Stock, String>, ObservableValue<String>>() {
        @Override
        public ObservableValue<String> call(CellDataFeatures<Stock, String> p) {
            return new SimpleStringProperty(p.getValue().getstockTicker());
        }
    };*/

Answer

jewelsea picture jewelsea · Jun 11, 2013

How to Fix It

The case of your getter and setter methods are wrong.

getstockTicker should be getStockTicker

setstockTicker should be setStockTicker

Some Background Information

Your PropertyValueFactory remains the same with:

new PropertyValueFactory<Stock,String>("stockTicker")

The naming convention will seem more obvious when you also add a property accessor to your Stock class:

public class Stock {

    private SimpleStringProperty stockTicker;

    public Stock(String stockTicker) {
        this.stockTicker = new SimpleStringProperty(stockTicker);
    }

    public String getStockTicker() {
        return stockTicker.get();
    }

    public void setStockTicker(String stockticker) {
        stockTicker.set(stockticker);
    }

    public StringProperty stockTickerProperty() {
        return stockTicker;
    }
}

The PropertyValueFactory uses reflection to find the relevant accessors. First it will try to use the stockTickerProperty accessor and, if that is not present fall back to getters and setters. Providing a property accessor is recommended as then you will automatically enable your table to observe the property in the underlying model, dynamically updating it's data as the underlying model changes.