Hvis du kan bruge java 8, kan du bruge den indbyggede FilteredList og prædikater. Her er noget, jeg skrev for at teste regex-filtrering. Jeg ændrede det lidt for at være mere som dit eksempel og bruge javafx 2.2, hvis det kræves. Bare skift nogle af de kommenterede linjer til at bruge java 8.
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
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.VBox;
import javafx.stage.Stage;
public class TableTest extends Application {
@Override
public void start(Stage primaryStage) {
ObservableList<LineItem> items = FXCollections.observableArrayList();
items.addAll(new LineItem("hello",123.45),
new LineItem("paid in full",0.01),
new LineItem("paid",0.01),
new LineItem("due",0.01),
new LineItem("paid",0.01));
//for java8
//FilteredList<LineItem> filteredItems = new FilteredList(items, e->true);
//not java8
ObservableList<LineItem> filteredItems = FXCollections.observableArrayList(items);
TableView tableView = new TableView(filteredItems);
TableColumn<LineItem,String> descCol = new TableColumn<>("desc");
descCol.setCellValueFactory(new PropertyValueFactory<>("desc"));
TableColumn<LineItem, Double> amountCol = new TableColumn<>("amount");
amountCol.setCellValueFactory(new PropertyValueFactory<>("amount"));
tableView.getColumns().addAll(descCol,amountCol);
TextField filterText = new TextField();
filterText.setPromptText("type filter and press enter");
filterText.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
//normal java8
//filteredItems.setPredicate(li -> li.desc.getValue().contains(filterText.getText()));
//regex java 8
//filteredItems.setPredicate(li -> li.desc.getValue().matches("(?i)"+filterText.getText()));
//not javafx 8
filteredItems.clear();
for (LineItem li: items)
if (li.desc.getValue().contains(filterText.getText()))
filteredItems.add(li);
}
});
VBox root = new VBox();
root.getChildren().addAll(tableView, filterText);
Scene scene = new Scene(root, 300, 300);
primaryStage.setTitle("Filter table test");
primaryStage.setScene(scene);
primaryStage.show();
}
public class LineItem {
private final StringProperty desc = new SimpleStringProperty();
private final DoubleProperty amount = new SimpleDoubleProperty();
public StringProperty descProperty() {return desc;}
public DoubleProperty amountProperty() {return amount;}
public LineItem(String dsc, double amt) {
desc.set(dsc); amount.set(amt);
}
}
}
todo, der er angiveligt en måde at binde prædikatetProperty på, men det kan jeg ikke finde ud af.
Rediger:Hvis du vil have en binding, i stedet for handleren til ActionEvent, skal du gøre noget lignende
filteredItems.predicateProperty().bind(
Bindings.createObjectBinding(() ->
li -> li.desc.getValue().contains(filterText.getText()),
filterText.textProperty())
);