Javafx PropertyValueFactory not populating Tableview
Asked Answered
M

2

18

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());
        }
    };*/
Melentha answered 11/6, 2013 at 2:3 Comment(0)
M
46
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.

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 (these should be public). 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 its data as the underlying model changes.

Morphosis answered 11/6, 2013 at 5:35 Comment(4)
Here's the most AGGRAVATING PART: ALL of my code uses a method naming convention like that. ALL of it (well except for that one snippet) I've spent DAYS on this issue... MY FREAKIN GOD!! THANK YOU!!!!Melentha
@Morphosis why getter called twice? and more than Person's object?Sculpturesque
Sorry UnKnown, I don't understand what you are asking. You might wish to ask a new question.Morphosis
One other point about this, since JavaFx is using reflection to find the methods, ensure the methods have public access.Android
P
-2

put the Getter and Setter method in you data class for all the elements.

Philosophism answered 29/12, 2016 at 18:0 Comment(1)
Could you be a little more specific? Please provide answers that don't require clarification from the asker. For more read How To Answer.Groundsill

© 2022 - 2024 — McMap. All rights reserved.