(Java FX) TableView 访问单元格内容进行搜索

问题描述 投票:0回答:1

我目前正在努力实现一个搜索框,它应该搜索(过滤的)TableView 的所有行和列。我希望搜索框直接过滤表中的项目,并且仅显示搜索字符串与任何当前显示的列中的任何文本匹配的行(正如用户所期望的那样)。

这就是我的问题:我想直接搜索单元格内容,而不仅仅是数据。 我不能对每个数据对象使用 toString() ,因为 toString() 和显示的值可能有很大不同(例如,布尔值表示为没有文本的复选框,这与搜索“false”不匹配, toString( ) 方法但是会)。 我尝试为每列生成一个带有 cellValueFactory 的空单元格并用数据填充它,但我无法访问 updateItem()-Method (它受保护),该方法生成单元格,根据文档我不应该这样做无论如何。

除了实现一个单元格,使 updateItem() 公开(这可能不应该完成),或手动存储所有转换器(这是乏味且耗时的,因为有很多不同的实体),你知道吗有没有更好的在 tableView 中搜索的解决方案?

java javafx tableview
1个回答
0
投票

如果我理解正确,您需要在过滤器中使用

OR
/
||
。鉴于您发布了零代码,很难知道。

import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
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.scene.text.Font;
import javafx.stage.Stage;

public class App extends Application
{

    private final TableView<Person> table = new TableView();
    private final ObservableList<Person> data = FXCollections.observableArrayList(
                                                    new Person("Jane", "Smith", "[email protected]"),
                                                    new Person("Isabella", "Jane", "[email protected]"),
                                                    new Person("Ethan", "Williams", "[email protected]"),
                                                    new Person("Emma", "Jones", "[email protected]"),
                                                    new Person("Michael", "Brown", "[email protected]")
                                                );

    public static void main(String[] args)
    {
        launch(args);
    }

    @Override
    public void start(Stage stage)
    {
        stage.setTitle("Table View Sample");
        stage.setWidth(450);
        stage.setHeight(550);

        Label label = new Label("Address Book");
        label.setFont(new Font("Arial", 20));

        TableColumn firstNameCol = new TableColumn("First Name");
        firstNameCol.setMinWidth(100);
        firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName"));

        TableColumn lastNameCol = new TableColumn("Last Name");
        lastNameCol.setMinWidth(100);
        lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName"));

        TableColumn emailCol = new TableColumn("Email");
        emailCol.setMinWidth(200);
        emailCol.setCellValueFactory(new PropertyValueFactory<Person, String>("email"));

        FilteredList<Person> flPerson = new FilteredList(data, p -> true);//Pass the data to a filtered list
        table.setItems(flPerson);//Set the table's items using the filtered list
        table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);

        TextField textField = new TextField();
        textField.setPromptText("Search here!");
        textField.textProperty().addListener((obs, oldValue, newValue) -> {
            flPerson.setPredicate((p) -> {
                return p.getFirstName().toLowerCase().contains(newValue.toLowerCase().trim()) || 
                p.getLastName().toLowerCase().contains(newValue.toLowerCase().trim()) ||
                p.getEmail().toLowerCase().contains(newValue.toLowerCase().trim());           
            });
        });
            
        final VBox root = new VBox();
        root.setSpacing(5);
        root.setPadding(new Insets(10, 0, 0, 10));
        root.getChildren().addAll(label, table, textField);

        Scene scene = new Scene(root);

        stage.setScene(scene);
        stage.show();
    }
                
    public static class Person
    {
        private final SimpleStringProperty firstName = new SimpleStringProperty();
        private final SimpleStringProperty lastName = new SimpleStringProperty();
        private final SimpleStringProperty email = new SimpleStringProperty();

        private Person(String fName, String lName, String email)
        {
            this.firstName.setValue(fName);
            this.lastName.setValue(lName);
            this.email.setValue(email);
        }

        public String getFirstName()
        {
            return firstName.get();
        }

        public void setFirstName(String fName)
        {
            firstName.set(fName);
        }
        
        public SimpleStringProperty getFirstNameProperty()
        {
            return firstName;
        }
        
        public String getLastName()
        {
            return lastName.get();
        }

        public void setLastName(String fName)
        {
            lastName.set(fName);
        }

        public SimpleStringProperty getLastNameProperty()
        {
            return lastName;
        }
        
        public String getEmail()
        {
            return email.get();
        }

        public void setEmail(String fName)
        {
            email.set(fName);
        }
        
        public SimpleStringProperty getEmailProperty()
        {
            return email;
        }
    }
}

更改代码来自 https://stackoverflow.com/a/47560767/2423906

输出

© www.soinside.com 2019 - 2024. All rights reserved.