GrrOink
GrrOink

Reputation: 11

PropertyValueFactory not filling my TableView

I'm having an issue where my TableView will not fill the table but information, but it DOES create the number of rows equal to the size of the List that I am passing into the Table when I call .setItems(). The Object class that I'm using has the correctly formatted naming conventions for the PropertyValueFactory (i believe) and I'm not sure why it wont load the information into the Table.

Here is my Controller, where I am uploading a .csv file, parsing through it and adding the information to the List 'formatted', which I pass at the end in .setItems().

public class ItemListViewController {
    @FXML
    private Button fileUploadButton;

    @FXML
    private TableView<CompareValue> infoTable;

    @FXML
    private AnchorPane mainPane;

    @FXML
    private Button homeButton;
    
    @FXML
    private TableColumn<CompareValue, Double> kitCostCol;

    @FXML
    private TableColumn<CompareValue, String> itemNameCol;
    
    @FXML
    private TableColumn<CompareValue, Double> fabCostCol;
    
    @FXML
    private TableColumn<CompareValue, Double> diffCol;

    @FXML
    void loadFile(ActionEvent event) throws Exception {
        FileChooser fc = new FileChooser();
        File selFile = fc.showOpenDialog(null);
        Scanner f;
        //List<CompareValue> itemList = new ArrayList<CompareValue>();
        ObservableList<CompareValue> formatted = FXCollections.observableArrayList();
        
        itemNameCol.setCellValueFactory(cellData -> cellData.getValue().itemNameProperty());
        fabCostCol.setCellValueFactory(new PropertyValueFactory<CompareValue, Double>("priceOfFabricator"));
        kitCostCol.setCellValueFactory(new PropertyValueFactory<CompareValue, Double>("priceOfKit"));
        
        if ( selFile != null ) {
            f = new Scanner(selFile);
            f.nextLine();                                       // Skips over the first line since its not of any use
            String curLine = "";
            String[] split;
            while ( f.hasNextLine() ) {
                curLine = f.nextLine();
                split = curLine.split(",");
                formatted.add(new CompareValue(split[0], Double.parseDouble(split[2]), Double.parseDouble(split[1])));
            }
            for ( CompareValue a : formatted ) {
                System.out.println(a.getItemName()+". "+a.getPriceOfKit());
            }
            infoTable.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
            infoTable.setItems(formatted);
        }
        else {
            System.out.println("File is not valid");
        }
    }
}

As a note, the List DOES contain all of the information that I want to pass, I checked by printing all of the values.

Here is the CompareValue class:

public class CompareValue {
    public SimpleStringProperty  itemName = new SimpleStringProperty();
    public SimpleDoubleProperty priceOfKit = new SimpleDoubleProperty();
    public SimpleDoubleProperty priceOfFabricator = new SimpleDoubleProperty();
    public SimpleDoubleProperty priceDifference = new SimpleDoubleProperty();
    
    public CompareValue() {
        
    }
    public CompareValue( String name, double pKit, double pFabricator ) {
        this.itemName = new SimpleStringProperty(name);
        this.priceOfKit = new SimpleDoubleProperty(pKit);
        this.priceOfFabricator = new SimpleDoubleProperty(pFabricator);
    }
    
    public void setItemName( String a ) {
        this.itemName = new SimpleStringProperty(a);
    }
    public void setPriceOfKit( double a ) {
        this.priceOfKit = new SimpleDoubleProperty(a);
    }
    public void setPriceOfFabricator( double a ) {
        this.priceOfFabricator = new SimpleDoubleProperty(a);
    }
    
    public String getItemName() {
        return this.itemName.get();
    }
    public double getPriceOfKit() {
        return this.priceOfKit.get();
    }
    public double getPriceOfFabricator() {
        return this.priceOfFabricator.get();
    }

    public SimpleStringProperty itemNameProperty() {
        return this.itemName;
    }
    
    public SimpleDoubleProperty priceOfKitProperty() {
        return this.priceOfKit;
    }
    
    public SimpleDoubleProperty priceOfFabricatorProperty() {
        return this.priceOfFabricator;
    }
    
    @Override
    public String toString() {
        return "Item Name: " + this.itemName +". Kit Price: " + this.priceOfKit + ". Price of Fab: " + this.priceOfFabricator;
    }
    
}

And here is the .fxml file

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane fx:id="mainPane" minHeight="720.0" minWidth="1280.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.controller.ItemListViewController">
   <children>
      <TableView fx:id="infoTable" editable="true" fixedCellSize="4.0" layoutX="40.0" layoutY="128.0" prefHeight="545.0" prefWidth="895.0">
        <columns>
          <TableColumn fx:id="itemNameCol" prefWidth="470.0" />
          <TableColumn fx:id="fabCostCol" minWidth="0.0" prefWidth="128.0" />
            <TableColumn fx:id="kitCostCol" prefWidth="135.0" />
            <TableColumn fx:id="diffCol" prefWidth="161.0" />
        </columns>
      </TableView>
      <Text layoutX="272.0" layoutY="89.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Data Table Information Loaded:">
         <font>
            <Font size="31.0" />
         </font>
      </Text>
      <Button fx:id="homeButton" layoutX="972.0" layoutY="648.0" mnemonicParsing="false" onAction="#goToHomePage" text="Home" />
      <Button fx:id="fileUploadButton" layoutX="966.0" layoutY="582.0" mnemonicParsing="false" onAction="#loadFile" text="Select .CSV file" />
   </children>
</AnchorPane>

Any help is appreciated :)

EDIT: This is the code from the class that loads in the .fxml file

public class MainViewController {

    @FXML
    private Button tableButton;

    @FXML
    private Button generateButton;

    @FXML
    private AnchorPane mainpane;
    @FXML
    void goToTableView(ActionEvent event) throws Exception {
        URL url = new File("src/application/view/ItemListView.fxml").toURI().toURL();                           //Switches the fxml file to the RoleView.fxml file
        mainpane = FXMLLoader.load(url);// pane you are GOING TO
        Scene scene = new Scene(mainpane);// pane you are GOING TO show
        Stage window = (Stage) ((Node)event.getSource()).getScene().getWindow();// pane you are ON
        window.setScene(scene);
        window.show();
    }
}

Sample data:

Item Name, Price of Fab., Price of Kit
Professional Killstreak Air Strike Kit, 1.40, 6.75
Professional Killstreak Ambassador Kit, 7.96, 14.39
Professional Killstreak Amputator Kit, 0.06, 5.26
Professional Killstreak Apoco-Fists Kit, 0.06, 6.22
Professional Killstreak Atomizer Kit, 0.07, 5.18
Professional Killstreak AWPer Hand Kit, 13.03, 19.50
Professional Killstreak Axtinguisher Kit, 0.36, 5.75
Professional Killstreak Baby Face's Blaster Kit, 0.80, 6.46
Professional Killstreak Back Scatter Kit, 0.10, 5.00
...
(159 lines)

I've already tried using lambda notation and it has not worked for me

Upvotes: 1

Views: 57

Answers (1)

James_D
James_D

Reputation: 209684

There's nothing wrong with any of the controller code. You can't see the data because you made the cells too small for the text to be visible. Remove the fixedCellSize = "4.0" from the FXML file (or at least set it to something reasonable).

As an aside, the setXXX methods in the model class are incorrect, and if they were ever called, your table would break. You should not create new Property instances (it's recommended to make these final). So you should have something like

public class CompareValue {
    private final SimpleStringProperty  itemName = new SimpleStringProperty();
    // ...
    
    public CompareValue() {
        
    }
    public CompareValue( String name, double pKit, double pFabricator ) {
        setItemName(name);
        setPriceOfKit(pKit);
        setPriceOfFabricator(pFabricator);
    }
    
    public final void setItemName( String a ) {
        this.itemNameProperty().set(a);
    }
    
    public final. String getItemName() {
        return this.itemNameProperty().get();
    }

    public SimpleStringProperty itemNameProperty() {
        return this.itemName;
    }

    // etc...    
}

Upvotes: 3

Related Questions