1
votes

So Im having Database, which contains Table with few parameters, one of those is "type" (TEXT). Im filling ComboBox with this "type" with this method:

public void loadTypefromDB()
{
    types = FXCollections.observableArrayList();
    try{
        ResultSet rs = conn.createStatement().executeQuery("SELECT type FROM Products");
        while(rs.next()){
            String product = rs.getString("type");
            types.add(product);
        }
    }
    catch (SQLException e) {
        e.printStackTrace();
    }
    choiceBox.setItems(types);
}

then I'm using this ComboBox to show all items of selected type in TableView.

public void choiceType(ActionEvent event)
{
    choiceBox.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() {
        @Override
        public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
            loadTypeDataFromDB(newValue.toString());
        }
    });
}

and here is loadTypeDataFromDB method which executes query with selected parameter

 public void loadTypeDataFromDB(String type){
    products = FXCollections.observableArrayList();

    try {
        PreparedStatement pst =  conn.prepareStatement("SELECT name, kcal, protein, carb, fat FROM Products WHERE type=?");
        pst.setString(1, type);
        ResultSet rs = pst.executeQuery();

        while(rs.next()){
            products.add(new productData(rs.getString("name"), rs.getString("kcal"), rs.getString("protein"), rs.getString("carb"), rs.getString("fat")));
        }
    }
    catch (SQLException e) {
        e.printStackTrace();
    }

    colProduct.setCellValueFactory(new PropertyValueFactory<productData, String>("name"));
    colKcal.setCellValueFactory(new PropertyValueFactory<productData, String>("kcal"));
    colProtein.setCellValueFactory(new PropertyValueFactory<productData, String>("protein"));
    colCarbs.setCellValueFactory(new PropertyValueFactory<productData, String>("carb"));
    colFat.setCellValueFactory(new PropertyValueFactory<productData, String>("fat"));

    tableProduct.setItems(null);
    tableProduct.setItems(products);
}

It ALMOST works correctly. I run my app, choose one of types from ComboBox and nothing happens (TableView stays clear). Then I choose other type from this ComboBox and suddenly it shows items of this type in TableView and from now on, I can display all types I want, everything works. So it looks like first choice from ComboBox is null (I dont get any exceptions tho). After first choice everything starts to work correctly...

1
If you debug, is the changed method called on first update? IE: Are you actually receiving a change event and the load method isn't working, or is the issue that the combo box isn't reporting anything? - Ironcache

1 Answers

1
votes

Your ChangeListener setup seems dubious to me, and likely the source of your problems (though, I can't know for certain without seeing more code):

public void choiceType(ActionEvent event)
{
    choiceBox.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() {
        @Override
        public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
            loadTypeDataFromDB(newValue.toString());
        }
    });
}

Where do you call this method? It takes an ActionEvent as the input; are you not setting up your listener until after you receive an event? Because that would certainly account for why you aren't seeing the first one.

Consider setting up the listener after adding the products (better still, where you create the ComboBox), and see if that helps:

public void loadTypefromDB()
{
    types = FXCollections.observableArrayList();
    try{
        ResultSet rs = conn.createStatement().executeQuery("SELECT type FROM Products");
        while(rs.next()){
            String product = rs.getString("type");
            types.add(product);
        }
    }
    catch (SQLException e) {
        e.printStackTrace();
    }
    choiceBox.setItems(types);
    choiceBox.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() {
        @Override
        public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
            loadTypeDataFromDB(newValue.toString());
        }
    });
}