Buscar elemento en un TableView JavaFX

Previamente hemos estudiado el control TableView de JavaFX por lo que en este tutorial desarrollaremos una pequeña aplicación para demostrar cómo podemos programar un cuadro de búsquedas para ubicar rápidamente un elemento que se encuentre dentro de este control, para esto utilizaremos una colección de tipo FilteredList<T>.

Lo primero que haremos será definir nuestra GUI mediante código JavaFX.

TableView<Person> tableView = new TableView<>();
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);

TableColumn<Person, String> tcNombre = new TableColumn<>("Nombre");
tcNombre.setCellValueFactory(c -> c.getValue().firstNameProperty());

TableColumn<Person, String> tcApellido = new TableColumn<>("Apellido");
tcApellido.setCellValueFactory(c -> c.getValue().lastNameProperty());

TableColumn<Person, Number> tcEdad = new TableColumn<>("Edad");
tcEdad.setCellValueFactory(c -> c.getValue().ageProperty());

tableView.getColumns().add(tcNombre);
tableView.getColumns().add(tcApellido);
tableView.getColumns().add(tcEdad);
tableView.setItems(createPersonList());

TextField search = new TextField();
search.setPromptText("Buscar...");
HBox.setHgrow(search, Priority.ALWAYS);

HBox searchBar = new HBox();
searchBar.getChildren().add(search);

VBox root = new VBox();
root.setSpacing(5.0);
root.setPadding(new Insets(10.0));
root.getChildren().addAll(searchBar, tableView);

Scene scene = new Scene(root, 800, 600);

primaryStage.setTitle("JavaFX Buscar en TableView");
primaryStage.setScene(scene);
primaryStage.show();

Este código produce el siguiente resultado:

Buscar elemento en TableView JavaFX

FilteredList

Para que el TableView<T> pueda filtrar sus elementos debemos proporcionarle un FilteredList<T> en lugar del ObservableList<T>, creamos fácilmente el primero a partir del segundo de la siguiente manera:

FilteredList<Person> filteredData = new FilteredList<>(createPersonList(), p -> true);
tableView.setItems(filteredData);

El predicate p -> true establece que inicialmente deseamos mostrar todos los elementos de la lista.

El siguiente paso es detectar los cambios en el TextField, cuando se escriba un nuevo texto aplicaremos un filtro basado en el mismo, por ejemplo, para filtrar los nombres que contengan el texto escrito por el usuario.

TextField search = new TextField();
search.setPromptText("Buscar...");
search.textProperty().addListener((prop, old, text) -> {
    filteredData.setPredicate(person -> {
        if(text == null || text.isEmpty()) return true;
        
        String name = person.getFirstName().toLowerCase();  
        return name.contains(text.toLowerCase());
    });
});

El método setPredicate() define el filtro de búsqueda, el objeto person define el elemento actual que estamos evaluando, verificamos si el primer nombre contiene el texto escrito en el cuadro de búsqueda, convertirnos ambos textos a minúsculas.

Cuadro de búsqueda para un TableView JavaFX

Si lo deseamos también podemos buscar por edad, por ejemplo aquellas personas mayores de 20 años, otra opción es buscar por apellido y utilizar los métodos de la clase String como: startsWith() para ubicar los apellidos que inicien con la palabra escrita o incluso usar una expresión regular para hacer coincidir patrones más complejos.

Para finalizar debo mencionar que al utilizar un FilteredList<T> la ordenación en el TableView<T> se deshabilita, al hacer clic sobre la cabecera de la columna esta no se ordenará, para activarlo haremos lo siguiente:

FilteredList<Person> filteredData = new FilteredList<>(createPersonList(), p -> true);

SortedList<Person> sortedData = new SortedList<>(filteredData);
sortedData.comparatorProperty().bind(tableView.comparatorProperty());

tableView.setItems(sortedData);

Con esto encapsulamos la lista dentro de un objeto SortedList<T> que representa una lista ordenada de elementos, luego enlazamos las propiedades comparatorProperty() del TableView<T> y este objeto, así activamos la característica de ordenación.

Descargar código: JavaFX Buscar en TableView.zip

Comentarios

Entradas populares de este blog

Conectar SQL Server con Java

Entrenar OpenCV en Detección de Objetos

Acceso a la webcam con OpenCV

JavaFx 8 Administrar ventanas

Conociendo la clase cv::Mat de OpenCV