Fast filtering in javafx tableview
Asked Answered
M

4

12

I need to implement a filter in javafx tableview with huge data (around 100,000 ),

I have tried this tutorial. It works but filtering is really slow as compared to swing sorting and filtering, code.

Can anyone help me to increase speed.

What is happening right now is as I type textproperty change fire up and filterdata but it is slow, I need something which shows filter result with typing quickly as happening in swing.

thanks in advance.

p.s I have also looked at this.

Magnate answered 10/6, 2013 at 5:28 Comment(5)
How is this any different from your previous question ?Algoid
sorting part is done I now need to add filter which filters out data according to text change in text box, I have given link for swing application or oracle website which works pretty fast (add 100,000) data point but my javafx application doesnot work fast (see link given in question for filtering in javafx)Magnate
For suggestion It is working with same speed as that of sorting but I want to know how swing implement it that it retrieve data too fast for filtering as compared to javafxMagnate
@ b.pradeep - Did you get any solution for this question?Splint
@IJP unfortunately no you have to write custom filtering by traversing through your table but JavaFx 8 looks promising, but I haven't explored it yet.Magnate
M
10

FilteredList

You may use FilteredList in JavaFX 8+.

ObservableList<YourObjectClass> actualList = ...;
FilteredList<YourObjectClass> filteredList = new FilteredList<>(actualList);

TableView table = ...;
table.setItems(filteredList);

// to filter
filteredList.setPredicate(
    new Predicate<YourObjectClass>(){
        public boolean test(YourObjectClass t){
            return false; // or true
        }
    }
);

as fast as swing, (maybe faster then swing... ). (I tested with 100000 rows)

Mandarin answered 5/9, 2015 at 17:15 Comment(0)
I
4

You can use the following code. It works fine for me..

ObservableList data =  table.getItems();
textfield.textProperty().addListener((ObservableValue<? extends String> observable, String oldValue, String newValue) -> {
            if (oldValue != null && (newValue.length() < oldValue.length())) {
                table.setItems(data);
            }
            String value = newValue.toLowerCase();
            ObservableList<T> subentries = FXCollections.observableArrayList();

            long count = table.getColumns().stream().count();
            for (int i = 0; i < table.getItems().size(); i++) {
                for (int j = 0; j < count; j++) {
                    String entry = "" + table.getColumns().get(j).getCellData(i);
                    if (entry.toLowerCase().contains(value)) {
                        subentries.add(table.getItems().get(i));
                        break;
                    }
                }
            }
            table.setItems(subentries);
        });
Ionogen answered 24/11, 2015 at 10:2 Comment(0)
C
1

I use this snippet of code for filtering but really i didn't test in huge data case

textField.textProperty().addListener(new InvalidationListener() {

        @Override
        public void invalidated(Observable observable) {
            if(textField.textProperty().get().isEmpty()) {
                tableView.setItems(dataList);
                return;
            }
            ObservableList<ClassModel> tableItems = FXCollections.observableArrayList();
            ObservableList<TableColumn<ClassModel, ?>> cols = tableView.getColumns();
            for(int i=0; i<dataList.size(); i++) {

                for(int j=0; j<cols.size(); j++) {
                    TableColumn col = cols.get(j);
                    String cellValue = col.getCellData(dataList.get(i)).toString();
                    cellValue = cellValue.toLowerCase();
                    if(cellValue.contains(textField.textProperty().get().toLowerCase())) {
                        tableItems.add(data.get(i));
                        break;
                    }                        
                }
            }
            tableView.setItems(tableItems);

        }
    });

where ClassModel is your Model Class

Cream answered 2/8, 2014 at 12:43 Comment(0)
S
1
@Override
public void initialize(URL arg0, ResourceBundle arg1)
{
    searchField. textProperty().addListener((obs, oldText, newText) -> { 
    search();
}); 
 

@FXML private void search()
{    
  String keyword = searchField.getText();
  if (keyword.equals("")) {
     table.setItems(data);
 } else {
     ObservableList<Product> filteredData = FXCollections.observableArrayList();
     for (Product product : data) {
         if(product.getName().contains(keyword))
             filteredData.add(product);
     }
   
     table.setItems(filteredData);
   }
}
Sarraute answered 16/5, 2021 at 23:11 Comment(1)
You may use thatSarraute

© 2022 - 2024 — McMap. All rights reserved.