FilteredList和SortedList

FilteredList和SortedList

我正在尝试使用Javafx8中的JFXTextField创建一个搜索栏。但是,当我在代码中添加FilteredListSortedList时,该应用程序不再运行,并且输出显示以下异常:

Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$154(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:748)
Caused by: javafx.fxml.LoadException: file:/C:/Users/Zed%20and%20White/Documents/NetBeansProjects/Project_EMS/dist/run1317715357/Project_EMS.jar!/project_ems/FrontEnd.fxml:22

at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
at project_ems.Project_EMS.start(Project_EMS.java:23)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$174(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
... 1 more
Caused by: java.lang.NullPointerException
at javafx.collections.transformation.TransformationList.<init>(TransformationList.java:65)
at javafx.collections.transformation.FilteredList.<init>(FilteredList.java:66)
at javafx.collections.transformation.FilteredList.<init>(FilteredList.java:87)
at project_ems.FrontEndController.<init>(FrontEndController.java:44)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(Class.java:442)
at sun.reflect.misc.ReflectUtil.newInstance(ReflectUtil.java:51)
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:927)
at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:971)
at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:220)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:744)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
... 17 more
Exception running application project_ems.Project_EMS


我已遵循此方法Create Search TextField to Search in a Javafx table

这是我的代码:

ObservableList:

private ObservableList<DataHandler_ExamsListing> EListingData;


使用上面的可观察列表的代码块:

private void LoadEListingData(){
    try {
        DBE.resultSet = DBE.statement.executeQuery("SELECT * FROM Exam");
        EListingData = FXCollections.observableArrayList();
        while (DBE.resultSet.next()) {
            EListingData.add(new DataHandler_ExamsListing(DBE.resultSet.getInt("ExamID"),DBE.resultSet.getString("ExamName"),DBE.resultSet.getString("ExamDate"),DBE.resultSet.getString("ExamComment")));
        }
        EListingTable.setItems(EListingData);
    } catch (SQLException e) {
    }
}


FilteredList和SortedList(均为全局):

private final FilteredList<DataHandler_ExamsListing> FilteredData = new FilteredList<>(EListingData);
private final SortedList<DataHandler_ExamsListing> sortedData = new SortedList<>(FilteredData);


SearchBar FXML:

@FXML // fx:id="SearchExam_Elisting"
private JFXTextField SearchExam_Elisting; // Value injected by FXMLLoader


SearchBar上的ActionEvent:

    @FXML
private void SearchExamList(ActionEvent event) {

    SearchExam_Elisting.textProperty().addListener((observable, oldValue, newValue) -> {
    FilteredData.setPredicate(DataHandler_ExamsListing -> {
        if (newValue == null || newValue.isEmpty()) {
            return true;
        }
        String lowerCaseFilter = newValue.toLowerCase();

        if (DataHandler_ExamsListing.getExamName().toLowerCase().contains(lowerCaseFilter)) {
            return true;
        }
        return false;
    });
      });
    sortedData.comparatorProperty().bind(EListingTable.comparatorProperty());
    EListingTable.setItems(sortedData);
    System.out.println("DOne");
}


如果我注释掉FilteredListSortedList以及ActionEvent,则该应用程序运行平稳。

请帮助我解决此问题。谢谢!

最佳答案

我不知道您所说的“两者都是全球性的”。最接近全局范围的是static字段,没有一个字段声明为static

但至于问题所在:

您在声明FilteredData字段时正在初始化它,这甚至导致在执行构造函数之前也会执行赋值。这意味着在分配之前无法执行LoadEListingData

FilteredData = new FilteredList<>(EListingData);


因此,当时EListingData仍为null。但这是不允许的。

您需要更改此字段的初始化时间,例如使用LoadEListingData加载数据后的。

或者,您可以使用空的ObservableList初始化字段,并在稍后调用LoadEListingData方法时填充此列表:

private final ObservableList<DataHandler_ExamsListing> EListingData = FXCollections.observableArrayList();
private final FilteredList<DataHandler_ExamsListing> FilteredData = new FilteredList<>(EListingData);
private final SortedList<DataHandler_ExamsListing> sortedData = new SortedList<>(FilteredData);

@FXML
private void initialize() {
    EListingTable.setItems(sortedData);
}

private void LoadEListingData(){
    List<DataHandler_ExamsListing> data = new ArrayList<>();
    try {
        // prepare data for insert using single update
        DBE.resultSet = DBE.statement.executeQuery("SELECT * FROM Exam"); // directly accessing static fields of a different class is a terrible idea since it violates the information hiding principle
        while (DBE.resultSet.next()) {
            data.add(new DataHandler_ExamsListing(DBE.resultSet.getInt("ExamID"),DBE.resultSet.getString("ExamName"),DBE.resultSet.getString("ExamDate"),DBE.resultSet.getString("ExamComment")));
        }
    } catch (SQLException e) {
        e.printStackTrace(); // Never just ignore an exception unless it's expected
        return;
    }
    // update data
    EListingData.setAll(data);
}

10-04 11:48