exSnake
exSnake

Reputation: 672

TableView not showing data until filter

I created this GUI in JavaFX

Java FX TableView

The problem is that when I try to run the readList function, after that, nothing will be shown in the table, but, if i try to filter with something, the data appear.

What I did wrong? Isn't the SortedList linked to the Filtered that is linked to the ObservableCollection that is watching the persons list? Should not auto-update the TableView whenever I change something in that list?

That's the controller

public class LetturaAwpController {

    List<Person> persons= new LinkedList<Person>();

    ObservableList<Person> observablePerson = FXCollections.observableList(persons);

    @FXML
    private TextField txtUser;

    @FXML
    private TextField txtPass;

    @FXML
    private TextField txtFiltraId;

    @FXML
    private CheckBox chkMag;

    @FXML
    private TableView<Person> tblMain;

    @FXML
    private TableColumn<Person, String> colId;

    @FXML
    void doRead(ActionEvent event) {

        if(txtPass.getText().isEmpty() | txtUser.getText().length() < 6)
            return;
        if (persons== null)
            persons= model.readList(txtUser.getText(), txtPass.getText());
        else
            persons.addAll(model.readList(txtUser.getText(), txtPass.getText()));
    }

    @FXML
    void initialize() {

        FilteredList<Person> filteredPerson= new FilteredList<>(observablePerson , p-> true);

        colId.setCellValueFactory(new PropertyValueFactory<Person,String>("idApparecchio"));    

        txtFiltraId.textProperty().addListener((observable, oldValue, newValue)-> {
            filteredSlot.setPredicate(person-> {
                if (newValue == null || newValue.isEmpty()){
                    return true;
                }

                String lowerCaseFilter = newValue.toLowerCase();

                if(person.getIdApparecchio().toLowerCase().contains(lowerCaseFilter)){
                    return true;
                } else if (person.getNomeModello().toLowerCase().contains(lowerCaseFilter)){
                    return true;
                }
                return false;
            });
        });

        SortedList<Person> sortedData = new SortedList<>(filteredPerson);

        // 4. Bind the SortedList comparator to the TableView comparator.
        sortedData.comparatorProperty().bind(tblMain.comparatorProperty());

        // 5. Add sorted (and filtered) data to the table.
        tblMain.setItems(sortedData);

    }

}

Upvotes: 0

Views: 81

Answers (1)

fabian
fabian

Reputation: 82491

Isn't the SortedList linked to the Filtered that is linked to the ObservableCollection

Yes and yes (Although there is no ObservableCollection, it's ObservableList)

that is watching the persons list?

No

The ObservableList is not watching the list that is passed to FXCollections.observableList, it creates a ObservableList that is backed by the List. Modifying the backing list will not notify listeners added to the ObservableList; the ObservableList just uses the backing list to store it's elements. FilteredList relies on a listener however.

This means: Do not access the backing list with write accesses. Modify the ObservableList instead:

observablePerson.addAll(model.readList(txtUser.getText(), txtPass.getText()));

Furthermore the if (persons== null) check is unnecessary, if you initialize the field and never modify it. Also simply replacing the field would result in the ObservableList being backed by a list different to the one stored in the field...

Upvotes: 1

Related Questions