分页的JavaFX TableView过滤(一起) [英] JavaFX TableView Filtering with Pagination (Together)

查看:132
本文介绍了分页的JavaFX TableView过滤(一起)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我分别对 TableView FilteringPagination进行了一些研究.

过滤: 帖子根据需要帮助了我
分页::

Person.java

public class Person {

    private final IntegerProperty sl;
    private final StringProperty firstName;
    private final StringProperty lastName;

    public Person(Integer sl, String firstName, String lastName) {
        this.sl = new SimpleIntegerProperty(sl);
        this.firstName = new SimpleStringProperty(firstName);
        this.lastName = new SimpleStringProperty(lastName);
    }

    public Integer getSl() {
        return sl.get();
    }

    public void setSl(Integer sl) {
        this.sl.set(sl);
    }

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

    public void setFirstName(String firstName) {
        this.firstName.set(firstName);
    }

    public String getLastName() {
        return lastName.get();
    }

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

}

Main.java

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Pagination and Filtering");        
        try {
            FXMLLoader loader = new FXMLLoader(Main.class.getResource("PersonTable.fxml"));
            AnchorPane page = (AnchorPane) loader.load();
            Scene scene = new Scene(page);
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

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

PersonTable.fxml

<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Pagination?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>

<AnchorPane minWidth="315.0" prefHeight="400.0" prefWidth="500.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="PersonTableController">
  <children>
    <HBox id="HBox" alignment="CENTER" spacing="5.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0">
      <children>
        <Label text="Filter Table:" />
        <TextField fx:id="filterField" prefWidth="-1.0" HBox.hgrow="ALWAYS" />
      </children>
    </HBox>
    <TableView fx:id="personTable" prefHeight="-1.0" prefWidth="-1.0" tableMenuButtonVisible="false" AnchorPane.bottomAnchor="60.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="40.0">
      <columns>
            <TableColumn fx:id="slColumn" maxWidth="5000.0" minWidth="10.0" prefWidth="120.0" text="SL" />
        <TableColumn fx:id="firstNameColumn" maxWidth="5000.0" minWidth="10.0" prefWidth="120.0" text="First Name" />
        <TableColumn fx:id="lastNameColumn" maxWidth="5000.0" minWidth="10.0" prefWidth="120.0" text="Last Name" />
      </columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
    </TableView>
      <HBox AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
         <children>
            <Pagination fx:id="pagination" />
         </children>
      </HBox>
  </children>
</AnchorPane>

任何帮助:) plz

这是我对您问题的简单解决方案:

import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
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.collections.transformation.SortedList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Pagination;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;

import java.net.URL;
import java.util.ResourceBundle;

public class Controller implements Initializable {

    @FXML
    private TextField filterField;
    @FXML
    private TableView<Person> personTable;
    @FXML
    private TableColumn<Person, Integer> slColumn;
    @FXML
    private TableColumn<Person, String> firstNameColumn;
    @FXML
    private TableColumn<Person, String> lastNameColumn;
    @FXML
    private Pagination pagination;

    private static final int ROWS_PER_PAGE = 4;
    private ObservableList<Person> masterData = FXCollections.observableArrayList();
    private FilteredList<Person> filteredData;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        setupData();
        filteredData = new FilteredList<>(masterData, p -> true);
        filterField.textProperty().addListener((observable, oldValue, newValue) -> {
            filteredData.setPredicate(
                    person -> newValue == null || newValue.isEmpty() || person.getFirstName().toLowerCase()
                            .contains(newValue.toLowerCase()) || person.getLastName().toLowerCase()
                            .contains(newValue.toLowerCase()));
            changeTableView(pagination.getCurrentPageIndex(), ROWS_PER_PAGE);
        });

        slColumn.setCellValueFactory(data -> data.getValue().slProperty().asObject());
        firstNameColumn.setCellValueFactory(data -> data.getValue().firstNameProperty());
        lastNameColumn.setCellValueFactory(data -> data.getValue().lastNameProperty());

        int totalPage = (int) (Math.ceil(masterData.size() * 1.0 / ROWS_PER_PAGE));
        pagination.setPageCount(totalPage);
        pagination.setCurrentPageIndex(0);
        changeTableView(0, ROWS_PER_PAGE);
        pagination.currentPageIndexProperty().addListener(
                (observable, oldValue, newValue) -> changeTableView(newValue.intValue(), ROWS_PER_PAGE));
    }

    public void setupData() {
        masterData.add(new Person(1, "Hans", "Muster"));
        masterData.add(new Person(2, "Ruth", "Mueller"));
        masterData.add(new Person(3, "Heinz", "Kurz"));
        masterData.add(new Person(4, "Cornelia", "Meier"));
        masterData.add(new Person(5, "Cornelia", "Meier"));
        masterData.add(new Person(6, "Werner", "Meyer"));
        masterData.add(new Person(7, "Lydia", "Kunz"));
        masterData.add(new Person(8, "Anna", "Best"));
        masterData.add(new Person(9, "Stefan", "Meier"));
        masterData.add(new Person(10, "Hans", "Muster"));
        masterData.add(new Person(11, "Ruth", "Mueller"));
        masterData.add(new Person(12, "Heinz", "Kurz"));
        masterData.add(new Person(13, "Werner", "Meyer"));
        masterData.add(new Person(14, "Lydia", "Kunz"));
    }

    private void changeTableView(int index, int limit) {

        int fromIndex = index * limit;
        int toIndex = Math.min(fromIndex + limit, masterData.size());

        int minIndex = Math.min(toIndex, filteredData.size());
        SortedList<Person> sortedData = new SortedList<>(
                FXCollections.observableArrayList(filteredData.subList(Math.min(fromIndex, minIndex), minIndex)));
        sortedData.comparatorProperty().bind(personTable.comparatorProperty());

        personTable.setItems(sortedData);

    }

    class Person {

        private final IntegerProperty sl;
        private final StringProperty firstName;
        private final StringProperty lastName;

        public Person(Integer sl, String firstName, String lastName) {
            this.sl = new SimpleIntegerProperty(sl);
            this.firstName = new SimpleStringProperty(firstName);
            this.lastName = new SimpleStringProperty(lastName);
        }

        public int getSl() {
            return sl.get();
        }

        public IntegerProperty slProperty() {
            return sl;
        }

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

        public StringProperty firstNameProperty() {
            return firstName;
        }

        public String getLastName() {
            return lastName.get();
        }

        public StringProperty lastNameProperty() {
            return lastName;
        }
    }
}

表过滤从第一页开始,如果它溢出",则从第二页开始,依此类推.这是预期的结果吗?

P.S.我重构/简化了一些代码,例如用lambda替换内部类,并删除了一些不必要的元素+将过滤扩展到姓氏,以获得更大的过滤可能性,但是您可以根据需要使用它们. /p>

I did some research on TableView's Filtering and Pagination separately.

Filtering : this post helped me as my need
Pagination : this, this post helped me also

I want to combine them together like so:

In Details --------------
I tried to make the pagination functionality first and it worked,
secondly, when i would start typing to the TextField filter functionality will match/filter the data from ObservableList, then rearrange the pagination according to the matched data size and show them through the table like the Datatable's search and pagination does and that's what i wanted, but i failed

My Code ...

PersonTableController.java

public class PersonTableController {

    @FXML private TextField filterField;
    @FXML private TableView<Person> personTable;
    @FXML private TableColumn<Person, Integer> slColumn;
    @FXML private TableColumn<Person, String> firstNameColumn;
    @FXML private TableColumn<Person, String> lastNameColumn;
    @FXML private Pagination pagination;
    private ObservableList<Person> masterData = FXCollections.observableArrayList();
    private int dataSize;
    private int rowsPerPage = 4;

    public PersonTableController() {
        masterData.add(new Person(1, "Hans", "Muster"));
        masterData.add(new Person(2, "Ruth", "Mueller"));
        masterData.add(new Person(3, "Heinz", "Kurz"));
        masterData.add(new Person(4, "Cornelia", "Meier"));
        masterData.add(new Person(5, "Cornelia", "Meier"));
        masterData.add(new Person(6, "Werner", "Meyer"));
        masterData.add(new Person(7, "Lydia", "Kunz"));
        masterData.add(new Person(8, "Anna", "Best"));
        masterData.add(new Person(9, "Stefan", "Meier"));
        masterData.add(new Person(10, "Hans", "Muster"));
        masterData.add(new Person(11, "Ruth", "Mueller"));
        masterData.add(new Person(12, "Heinz", "Kurz"));
        masterData.add(new Person(13, "Werner", "Meyer"));
        masterData.add(new Person(14, "Lydia", "Kunz"));
    }

    @FXML
    private void initialize() {

        dataSize = masterData.size();

        pagination.currentPageIndexProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                changeTableView(newValue.intValue(), rowsPerPage);
            }

        });

        FilteredList<Person> filteredData = new FilteredList<>(masterData, p -> true);

        filterField.textProperty().addListener((observable, oldValue, newValue) -> {
            filteredData.setPredicate(person -> {
                if (newValue == null || newValue.isEmpty())
                    return true;
                String lowerCaseFilter = newValue.toLowerCase();

                if (person.getFirstName().toLowerCase().indexOf(lowerCaseFilter) != -1) {
                    return true; // Filter matches first name.
                }
                return false; // Does not match.
            });
        });

        SortedList<Person> sortedData = new SortedList<>(filteredData);
        sortedData.comparatorProperty().bind(personTable.comparatorProperty());
        // personTable.setItems(sortedData);

        slColumn.setCellValueFactory(new PropertyValueFactory<Person, Integer>("sl"));
        firstNameColumn.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName"));
        lastNameColumn.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName"));


        int totalPage = (int) (Math.ceil(dataSize * 1.0 / rowsPerPage));
        pagination.setPageCount(totalPage);
        pagination.setCurrentPageIndex(0);
        changeTableView(0, rowsPerPage);

    }

    private void changeTableView(int index, int limit) {

        int fromIndex = index * limit;
        int toIndex = Math.min(fromIndex + limit, dataSize);

        List<Person> subListObs = masterData.subList(fromIndex, toIndex);
        ObservableList<Person> tmpObsToSetTableVal = FXCollections.observableArrayList();

        personTable.getItems().clear();
        personTable.setItems(null);

        for (Person t : subListObs) {
            tmpObsToSetTableVal.add(t);
        }

        personTable.setItems(tmpObsToSetTableVal);

    }

}

Person.java

public class Person {

    private final IntegerProperty sl;
    private final StringProperty firstName;
    private final StringProperty lastName;

    public Person(Integer sl, String firstName, String lastName) {
        this.sl = new SimpleIntegerProperty(sl);
        this.firstName = new SimpleStringProperty(firstName);
        this.lastName = new SimpleStringProperty(lastName);
    }

    public Integer getSl() {
        return sl.get();
    }

    public void setSl(Integer sl) {
        this.sl.set(sl);
    }

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

    public void setFirstName(String firstName) {
        this.firstName.set(firstName);
    }

    public String getLastName() {
        return lastName.get();
    }

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

}

Main.java

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Pagination and Filtering");        
        try {
            FXMLLoader loader = new FXMLLoader(Main.class.getResource("PersonTable.fxml"));
            AnchorPane page = (AnchorPane) loader.load();
            Scene scene = new Scene(page);
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

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

PersonTable.fxml

<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Pagination?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>

<AnchorPane minWidth="315.0" prefHeight="400.0" prefWidth="500.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="PersonTableController">
  <children>
    <HBox id="HBox" alignment="CENTER" spacing="5.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0">
      <children>
        <Label text="Filter Table:" />
        <TextField fx:id="filterField" prefWidth="-1.0" HBox.hgrow="ALWAYS" />
      </children>
    </HBox>
    <TableView fx:id="personTable" prefHeight="-1.0" prefWidth="-1.0" tableMenuButtonVisible="false" AnchorPane.bottomAnchor="60.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="40.0">
      <columns>
            <TableColumn fx:id="slColumn" maxWidth="5000.0" minWidth="10.0" prefWidth="120.0" text="SL" />
        <TableColumn fx:id="firstNameColumn" maxWidth="5000.0" minWidth="10.0" prefWidth="120.0" text="First Name" />
        <TableColumn fx:id="lastNameColumn" maxWidth="5000.0" minWidth="10.0" prefWidth="120.0" text="Last Name" />
      </columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
    </TableView>
      <HBox AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
         <children>
            <Pagination fx:id="pagination" />
         </children>
      </HBox>
  </children>
</AnchorPane>

any help :) plz

解决方案

here is my simple solution to your problem:

import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
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.collections.transformation.SortedList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Pagination;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;

import java.net.URL;
import java.util.ResourceBundle;

public class Controller implements Initializable {

    @FXML
    private TextField filterField;
    @FXML
    private TableView<Person> personTable;
    @FXML
    private TableColumn<Person, Integer> slColumn;
    @FXML
    private TableColumn<Person, String> firstNameColumn;
    @FXML
    private TableColumn<Person, String> lastNameColumn;
    @FXML
    private Pagination pagination;

    private static final int ROWS_PER_PAGE = 4;
    private ObservableList<Person> masterData = FXCollections.observableArrayList();
    private FilteredList<Person> filteredData;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        setupData();
        filteredData = new FilteredList<>(masterData, p -> true);
        filterField.textProperty().addListener((observable, oldValue, newValue) -> {
            filteredData.setPredicate(
                    person -> newValue == null || newValue.isEmpty() || person.getFirstName().toLowerCase()
                            .contains(newValue.toLowerCase()) || person.getLastName().toLowerCase()
                            .contains(newValue.toLowerCase()));
            changeTableView(pagination.getCurrentPageIndex(), ROWS_PER_PAGE);
        });

        slColumn.setCellValueFactory(data -> data.getValue().slProperty().asObject());
        firstNameColumn.setCellValueFactory(data -> data.getValue().firstNameProperty());
        lastNameColumn.setCellValueFactory(data -> data.getValue().lastNameProperty());

        int totalPage = (int) (Math.ceil(masterData.size() * 1.0 / ROWS_PER_PAGE));
        pagination.setPageCount(totalPage);
        pagination.setCurrentPageIndex(0);
        changeTableView(0, ROWS_PER_PAGE);
        pagination.currentPageIndexProperty().addListener(
                (observable, oldValue, newValue) -> changeTableView(newValue.intValue(), ROWS_PER_PAGE));
    }

    public void setupData() {
        masterData.add(new Person(1, "Hans", "Muster"));
        masterData.add(new Person(2, "Ruth", "Mueller"));
        masterData.add(new Person(3, "Heinz", "Kurz"));
        masterData.add(new Person(4, "Cornelia", "Meier"));
        masterData.add(new Person(5, "Cornelia", "Meier"));
        masterData.add(new Person(6, "Werner", "Meyer"));
        masterData.add(new Person(7, "Lydia", "Kunz"));
        masterData.add(new Person(8, "Anna", "Best"));
        masterData.add(new Person(9, "Stefan", "Meier"));
        masterData.add(new Person(10, "Hans", "Muster"));
        masterData.add(new Person(11, "Ruth", "Mueller"));
        masterData.add(new Person(12, "Heinz", "Kurz"));
        masterData.add(new Person(13, "Werner", "Meyer"));
        masterData.add(new Person(14, "Lydia", "Kunz"));
    }

    private void changeTableView(int index, int limit) {

        int fromIndex = index * limit;
        int toIndex = Math.min(fromIndex + limit, masterData.size());

        int minIndex = Math.min(toIndex, filteredData.size());
        SortedList<Person> sortedData = new SortedList<>(
                FXCollections.observableArrayList(filteredData.subList(Math.min(fromIndex, minIndex), minIndex)));
        sortedData.comparatorProperty().bind(personTable.comparatorProperty());

        personTable.setItems(sortedData);

    }

    class Person {

        private final IntegerProperty sl;
        private final StringProperty firstName;
        private final StringProperty lastName;

        public Person(Integer sl, String firstName, String lastName) {
            this.sl = new SimpleIntegerProperty(sl);
            this.firstName = new SimpleStringProperty(firstName);
            this.lastName = new SimpleStringProperty(lastName);
        }

        public int getSl() {
            return sl.get();
        }

        public IntegerProperty slProperty() {
            return sl;
        }

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

        public StringProperty firstNameProperty() {
            return firstName;
        }

        public String getLastName() {
            return lastName.get();
        }

        public StringProperty lastNameProperty() {
            return lastName;
        }
    }
}

The table filtering begins on the first page, and if it "overflows" then on the second and so on. This is the expected result?

P.S. I refactored/simplified a little bit the code, like replace the inner classes with lambdas and removed a few unnecessary element + extended the filtering to last name, to get a larger amount of filter possibility, but you can use them as you want.

这篇关于分页的JavaFX TableView过滤(一起)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆