Filtrare e ordinare una TableView in JavaFX

Mattepuffo's logo
Filtrare e ordinare una TableView in JavaFX

Filtrare e ordinare una TableView in JavaFX

In questo articolo avevamo visto come riempire una TableView da database in JavaFX.

Qui vediamo come impostare ordinamento a filtro; in pratica potremmo ordinare la tabella cliccando sull'intestazione, ed eseguire ricerche attraverso una casella di testo.

Da dove prendiamo i dati, in questo caso, non è importante; quindi tralascerò come riempire la lista.

Partiamo dall'intestazione:

public class TableColumns {

    public static ArrayList setcols() {
        String[] arrCols = {"Id", "Title", "Author", 
"Editor", "Price", "Isbn", "Note"};
        ArrayList tbc = new ArrayList<>();
        for (int i = 0; i < arrCols.length; i++) {
            TableColumn tc = new TableColumn(arrCols[i]);
            tc.setCellValueFactory(
                    new PropertyValueFactory<Book, String>(arrCols[i].toLowerCase())
            );
            tbc.add(tc);
        }
        return tbc;
    }
}

Attenzione ai nomi delle colonne....

Per ogni riga useremo un oggetto custom, che corrisponde a questa classe qui:

public class Book {

    private String id;
    private String title;
    private String author;
    private String editor;
    private String price;
    private String isbn;
    private String note;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getEditor() {
        return editor;
    }

    public void setEditor(String editor) {
        this.editor = editor;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    public String getIsbn() {
        return isbn;
    }

    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }
}

Nel nostro controller:

public class ControllerMain {

    @FXML
    private TableView tblBooks;

    @FXML
    private TextField txtSearch;

    @FXML
    public void initialize() {
        setTable();
    }

    private void setTable() {
        try {
            List listBooks = ... // QUA RIEMPITE LA LISTA
            ObservableList list = FXCollections.observableArrayList(listBooks);
            tblBooks.getColumns().setAll(TableColumns.setcols());
            tblBooks.setItems(list);
            FilteredList filteredData = new FilteredList<>(list, f -> true);
            txtSearch.textProperty().addListener((observable, oldValue, newValue) -> {
                filteredData.setPredicate(film -> {
                    if (newValue == null || newValue.isEmpty()) {
                        return true;
                    }
                    String lowerCaseFilter = newValue.toLowerCase();
                    if (film.getTitle().toLowerCase().contains(lowerCaseFilter)) {
                        return true;
                    } else if (film.getNote().contains(lowerCaseFilter)) {
                        return true;
                    }
                    return false;
                });
            });
            SortedList sortedList = new SortedList<>(filteredData);
            sortedList.comparatorProperty().bind(tblBooks.comparatorProperty());
            tblBooks.setItems(sortedList);
        } catch (IOException ex) {            
        }
    }
}

Ripeto, vi ho messo solo l'essenziale, senza indicare come rimpire la lista di Book.

Per finire, questo il layout:

<BorderPane xmlns="http://javafx.com/javafx/8.0.112" 
            xmlns:fx="http://javafx.com/fxml/1"
            fx:controller="com.mp.book.ControllerMain">
    <top>
        <VBox>
            <children>
                <FlowPane>
                    <children>
                        <TextField fx:id="txtSearch" promptText="Cerca..."/>
                    </children>
                </FlowPane>
            </children>
        </VBox>
    </top>
    <center>
        <TableView fx:id="tblBooks" BorderPane.alignment="CENTER"/>
    </center>
</BorderPane>

Ovviamente disponete i componenti come volete voi.

Enjoy!


Condividi

Commentami!