/* * Copyright 2016 Bekwam, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.bekwam.examples.javafx.table; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; import javax.inject.Inject; import javax.inject.Provider; import javafx.collections.ObservableList; import javafx.collections.transformation.FilteredList; import javafx.collections.transformation.SortedList; import javafx.concurrent.Task; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.ProgressBar; import javafx.scene.control.SelectionMode; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.TextField; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.layout.HBox; /** * @author carl_000 */ public class PersonsController { private Logger logger = Logger.getLogger("com.bekwam.examples.javafx.table"); @FXML TableView<Person> tblPersons; @FXML TableColumn<Person, String> tcType; @FXML TableColumn<Person, String> tcFirstName; @FXML TableColumn<Person, String> tcLastName; @FXML TableColumn<Person, String> tcEmail; @FXML ProgressBar pbStatus; @FXML Label lblStatus; @FXML HBox hboxStatus; @FXML TextField tfFilter; @FXML Button btnAdd; @Inject PersonDAO dao; @Inject Provider<PersonsCellFactory> personsCellFactoryProvider; @Inject Provider<PersonTypeCellFactory> personTypeCellFactoryProvider; private final ObservableList<Person> personsActiveRecord; @Inject public PersonsController(ObservableList<Person> personsActiveRecord) { this.personsActiveRecord = personsActiveRecord; } @FXML public void initialize() { PersonTypeCellFactory ptcf = personTypeCellFactoryProvider.get(); ptcf.setDeletePersonsHandler((evt) -> deletePersons()); tcType.setCellValueFactory( new PropertyValueFactory<Person, String>("personType") ); tcType.setCellFactory(ptcf); PersonsCellFactory pcf1 = personsCellFactoryProvider.get(); pcf1.setDeletePersonsHandler((evt) -> deletePersons()); tcFirstName.setCellValueFactory( new PropertyValueFactory<Person, String>("firstName") ); tcFirstName.setCellFactory(pcf1); PersonsCellFactory pcf2 = personsCellFactoryProvider.get(); pcf2.setDeletePersonsHandler((evt) -> deletePersons()); tcLastName.setCellValueFactory( new PropertyValueFactory<Person, String>("lastName") ); tcLastName.setCellFactory(pcf2); PersonsCellFactory pcf3 = personsCellFactoryProvider.get(); pcf3.setDeletePersonsHandler((evt) -> deletePersons()); tcEmail.setCellValueFactory( new PropertyValueFactory<Person, String>("email") ); tcEmail.setCellFactory(pcf3); tblPersons.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); hboxStatus.setVisible( false ); tblPersons.setItems( personsActiveRecord ); btnAdd.disableProperty().bind( tfFilter.textProperty().isNotEmpty()); } @FXML public void addPerson() { final Person p = new Person(); // tblPersons.getItems().add(p); personsActiveRecord.add(p); Task<Long> task = new Task<Long>() { @Override protected Long call() throws Exception { updateProgress(0.1d, 1.0d); updateMessage( "Saving person"); Long personId = dao.addPerson(p); return personId; } @Override protected void succeeded() { super.succeeded(); updateProgress(1.0d, 1.0d); updateMessage("Save completed"); p.setPersonId(getValue()); // sets obj in UI and in AR } }; hboxStatus.visibleProperty().bind( task.runningProperty() ); pbStatus.progressProperty().bind( task.progressProperty() ); lblStatus.textProperty().bind( task.messageProperty() ); new Thread(task).start(); } @FXML public void deletePersons() { List<Long> personIds = tblPersons .getSelectionModel() .getSelectedItems() .stream() .map(Person::getPersonId) .collect(Collectors.toList()); personsActiveRecord.removeAll(tblPersons.getSelectionModel().getSelectedItems()); // this has to be called last b/c selection will be removed too //tblPersons.getItems().removeAll(tblPersons.getSelectionModel().getSelectedItems()); Task<Void> task = new Task<Void>() { @Override protected Void call() throws Exception { dao.deletePersons(personIds); return null; } }; hboxStatus.visibleProperty().bind( task.runningProperty() ); pbStatus.progressProperty().bind( task.progressProperty() ); lblStatus.textProperty().bind( task.messageProperty() ); new Thread(task).start(); } @FXML public void clearFilter() { tfFilter.textProperty().set(""); doFilterTable( tfFilter ); } protected void doFilterTable(TextField tf) { String criteria = tf.getText(); if( logger.isLoggable(Level.FINE) ) { logger.fine( "[FILTER] filtering on=" + criteria ); } if( criteria == null || criteria.isEmpty() ) { tblPersons.setItems( personsActiveRecord ); return; } FilteredList<Person> fl = new FilteredList<>(personsActiveRecord, p -> true); fl.setPredicate(person -> { if (criteria == null || criteria.isEmpty()) { return true; } String lcCriteria = criteria.toLowerCase(); if (person.getFirstName().toLowerCase().contains(lcCriteria)) { return true; // Filter matches first name. } else if (person.getLastName().toLowerCase().contains(lcCriteria)) { return true; // Filter matches last name. } else if (person.getEmail().toLowerCase().contains(lcCriteria)) { return true; // matches email } return false; // Does not match. }); SortedList<Person> sortedData = new SortedList<>(fl); sortedData.comparatorProperty().bind(tblPersons.comparatorProperty()); // ? tblPersons.setItems(sortedData); } @FXML public void filterTable(ActionEvent evt) { doFilterTable( (TextField)evt.getSource() ); } @FXML public void refresh() { Task<List<Person>> task = new Task<List<Person>>() { @Override public List<Person> call() throws Exception { List<Person> persons = dao.findAll(); return persons; } @Override protected void succeeded() { super.succeeded(); tblPersons.getItems().clear(); tblPersons.getItems().addAll( getValue() ); } }; hboxStatus.visibleProperty().bind( task.runningProperty() ); pbStatus.progressProperty().bind( task.progressProperty() ); lblStatus.textProperty().bind( task.messageProperty() ); new Thread(task).start(); } }