这是我之前发布的问题的后续内容
here
.
TableView
显示列表
Person
物体。在名单上方,我有一个
TextField
我用它来过滤
表视图
.
这个
人
userId
,
lastName
emailAddress
.
但是,我现在需要根据匹配的字段对结果进行排序
和
用户
Type
.
个人.java
:
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public final class Person {
private StringProperty userType = new SimpleStringProperty();
private IntegerProperty userId = new SimpleIntegerProperty();
private StringProperty firstName = new SimpleStringProperty();
private StringProperty lastName = new SimpleStringProperty();
private StringProperty emailAddress = new SimpleStringProperty();
public Person(String type, int id, String firstName, String lastName, String emailAddress) {
this.userType.set(type);
this.userId.set(id);
this.firstName.set(firstName);
this.lastName.set(lastName);
this.emailAddress.set(emailAddress);
}
public String getUserType() {
return userType.get();
}
public void setUserType(String userType) {
this.userType.set(userType);
}
public StringProperty userTypeProperty() {
return userType;
}
public int getUserId() {
return userId.get();
}
public void setUserId(int userId) {
this.userId.set(userId);
}
public IntegerProperty userIdProperty() {
return userId;
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String firstName) {
this.firstName.set(firstName);
}
public StringProperty firstNameProperty() {
return firstName;
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String lastName) {
this.lastName.set(lastName);
}
public StringProperty lastNameProperty() {
return lastName;
}
public String getEmailAddress() {
return emailAddress.get();
}
public void setEmailAddress(String emailAddress) {
this.emailAddress.set(emailAddress);
}
public StringProperty emailAddressProperty() {
return emailAddress;
}
}
主类
:
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.collections.transformation.SortedList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
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;
import java.util.Comparator;
public class Main extends Application {
TableView<Person> tableView;
private TextField txtSearch;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
// Simple Interface
VBox root = new VBox(10);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(10));
// Create the TableView of data
tableView = new TableView<>();
TableColumn<Person, Integer> colId = new TableColumn<>("ID");
TableColumn<Person, String> colFirstName = new TableColumn<>("First Name");
TableColumn<Person, String> colLastName = new TableColumn<>("Last Name");
TableColumn<Person, String> colEmailAddress = new TableColumn<>("Email Address");
// Set the ValueFactories
colId.setCellValueFactory(new PropertyValueFactory<>("userId"));
colFirstName.setCellValueFactory(new PropertyValueFactory<>("firstName"));
colLastName.setCellValueFactory(new PropertyValueFactory<>("lastName"));
colEmailAddress.setCellValueFactory(new PropertyValueFactory<>("emailAddress"));
// Add columns to the TableView
tableView.getColumns().addAll(colId, colFirstName, colLastName, colEmailAddress);
// Create the filter/search TextField
txtSearch = new TextField();
txtSearch.setPromptText("Search ...");
addSearchFilter(getPersons());
// Add the controls to the layout
root.getChildren().addAll(txtSearch, tableView);
// Show the stage
primaryStage.setScene(new Scene(root));
primaryStage.setTitle("Sample");
primaryStage.show();
}
private void addSearchFilter(ObservableList<Person> list) {
FilteredList<Person> filteredList = new FilteredList<Person>(list);
txtSearch.textProperty().addListener(((observable, oldValue, newValue) ->
filteredList.setPredicate(person -> {
// Clear any currently-selected item from the TableView
tableView.getSelectionModel().clearSelection();
// If search field is empty, show everything
if (newValue == null || newValue.trim().isEmpty()) {
return true;
}
// Grab the trimmed search string
String query = newValue.trim().toLowerCase();
// Convert the query to an array of individual search terms
String[] keywords = query.split("[\\s]+");
// Create a single string containing all the data we will match against
// BONUS QUESTION: Is there a better way to do this?
String matchString =
String.valueOf(person.getUserId())
+ person.getLastName().toLowerCase()
+ person.getEmailAddress().toLowerCase();
// Check if ALL the keywords exist in the matchString; if any are absent, return false;
for (String keyword : keywords) {
if (!matchString.contains(keyword)) return false;
}
// All entered keywords exist in this Person's searchable fields
return true;
})));
SortedList<Person> sortedList = new SortedList<>(filteredList);
// Create the Comparator to allow ranking of search results
Comparator<Person> comparator = new Comparator<Person>() {
@Override
public int compare(Person person, Person t1) {
return 0;
}
};
// Set the comparator and bind list to the TableView
sortedList.setComparator(comparator);
tableView.setItems(sortedList);
}
private ObservableList<Person> getPersons() {
ObservableList<Person> personList = FXCollections.observableArrayList();
personList.add(new Person("DECEASED", 123, "Chrissie", "Watkins", "fishfood@email.com"));
personList.add(new Person("VET", 342, "Matt", "Hooper", "m.hooper@noaa.gov"));
personList.add(new Person("VET", 526, "Martin", "Brody", "chiefofpolice@amity.gov"));
personList.add(new Person("NEW", 817, "Larry", "Vaughn", "lvaughn@amity.gov"));
return personList;
}
}
你会看到我有一个空的
Comparator
在我的
Main
previous question
):
Comparator<DataItem> byName = new Comparator<DataItem>() {
@Override
public int compare(DataItem o1, DataItem o2) {
String searchKey = txtSearch.getText().toLowerCase();
int item1Score = findScore(o1.getName().toLowerCase(), searchKey);
int item2Score = findScore(o2.getName().toLowerCase(), searchKey);
if (item1Score > item2Score) {
return -1;
}
if (item2Score > item1Score) {
return 1;
}
return 0;
}
private int findScore(String item1Name, String searchKey) {
int sum = 0;
if (item1Name.startsWith(searchKey)) {
sum += 2;
}
if (item1Name.contains(searchKey)) {
sum += 1;
}
return sum;
}
};
不过,我不知道如何将其应用于多个领域。具体来说,我希望能够选择哪些领域应该排名“更高”
对于本例,我要完成的是按以下顺序对列表进行排序:
-
用户ID
从一个
keyword
-
姓氏
从一个
-
电子邮件地址
从一个
关键字
-
姓氏
关键字
-
电子邮件地址
包含
关键字
-
在匹配的任何
userType = "VET"
应该先列出来
StackOverflow上有几个帖子处理按多个字段排序的问题,但我发现的所有帖子都在比较
人
到
人
txtSearch.getText()
价值观。
比较器
设置这种性质的自定义排序?