JavaFX setCellValueFactory无法检索属性IllegalAcessException

我已经检查了该主题上的至少20个其他线程,并尝试尽我所能进行调试,但是我不知道为什么它不起作用。我希望我的“ addButton”在按下按钮时将数据从TextBoxes添加到TableView中。

我的数据类:

package org.application;

import javafx.beans.property.SimpleStringProperty;

public class credits {
    private SimpleStringProperty title;
    private SimpleStringProperty occupation;
    private SimpleStringProperty person;

    public credits (String title,String occupation,String person){
        this.title = new SimpleStringProperty(title);
        this.occupation = new SimpleStringProperty(occupation);
        this.person = new SimpleStringProperty(person);
    }

    public String getTitle() {
        return this.title.get();
    }

    public void setTitle(String title) {
        this.title.set(title);
    }

    public String getOccupation() {
        return this.occupation.get();
    }

    public void setOccupation(String occupation) {
        this.occupation.set(occupation);
    }

    public String getPerson() {
        return this.person.get();
    }

    public void setPerson(String name) {
        this.person.set(name);
    }

}

Controller类重要部分的摘要

    public Button searchButton;
    public Button addButton;
    public Button deleteButton;
    public Button updateButton;
    public TextField searchBox;
    public TextField setTitleBox;
    public TextField setOccupationBox;
    public TextField setPersonBox;
    public TableView creditTable;
    public TableColumn title;
    public TableColumn occupation;
    public TableColumn person;
    public ListView test;

    final ObservableList<credits> credits = FXCollections.observableArrayList();

    public void initialize() {
        title.setCellValueFactory(new PropertyValueFactory<credits,String>("title"));
        occupation.setCellValueFactory(new PropertyValueFactory<credits,String>("occupation"));
        person.setCellValueFactory(new PropertyValueFactory<credits,String>("person"));
    }

    public void addButton(actionEvent event) {
        String title = setTitleBox.getText();
        String occupation = setOccupationBox.getText();
        String person = setPersonBox.getText();
        credits.add(new credits(title,occupation,person));
        creditTable.setItems(credits);
    }

fxml文件:

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="800.0" styleclass="rightSide" stylesheets="@../../ECMS.css" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.presentation.Mainmenu">
   <children>
      <Button fx:id="loginButton" layoutX="14.0" layoutY="14.0" mnemonicParsing="false" onaction="#switchToLoginScreen" styleclass="loginButton" text="Login" />
      <TextField fx:id="searchBox" layoutX="14.0" layoutY="108.0" prefHeight="30.0" prefWidth="195.0" promptText="Name" />
      <Button fx:id="searchButton" layoutX="214.0" layoutY="108.0" mnemonicParsing="false" prefHeight="30.0" prefWidth="100.0" styleclass="loginButton" text="Search" />
      <Button fx:id="helpButton" layoutX="63.0" layoutY="14.0" mnemonicParsing="false" onaction="#switchToHelpPopup" styleclass="loginButton" text="Help" />
      <Label layoutX="14.0" layoutY="86.0" prefHeight="17.0" prefWidth="162.0" text="Search for productions:">

         <font>
            <Font name="Ebrima Bold" size="14.0" />
         </font></Label>
      <ListView fx:id="test" layoutX="14.0" layoutY="143.0" prefHeight="450.0" prefWidth="300.0" />
      <Button fx:id="closeButton" layoutX="775.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onaction="#closeButtonaction" prefHeight="20.0" prefWidth="25.0" styleclass="closeButton" text="X">
         <font>
            <Font name="Eras Bold ITC" size="12.0" />
         </font></Button>
      <Button fx:id="addButton" layoutX="363.0" layoutY="93.0" mnemonicParsing="false" onaction="#addButton" prefHeight="31.0" prefWidth="100.0" text="Add" />
      <Button fx:id="deleteButton" layoutX="504.0" layoutY="93.0" mnemonicParsing="false" prefHeight="31.0" prefWidth="100.0" text="Delete" />
      <Button fx:id="updateButton" layoutX="652.0" layoutY="93.0" mnemonicParsing="false" prefHeight="31.0" prefWidth="100.0" text="Update" />
      <TableView fx:id="creditTable" editable="true" layoutX="332.0" layoutY="143.0" prefHeight="450.0" prefWidth="450.0">
        <columns>
          <TableColumn fx:id="title" prefWidth="147.0" text="Title" />
          <TableColumn fx:id="occupation" minWidth="0.0" prefWidth="132.0" text="Occupation" />
            <TableColumn fx:id="person" minWidth="-1.0" prefWidth="170.0" text="Person" />
        </columns>
      </TableView>
      <TextField fx:id="setPersonBox" layoutX="634.0" layoutY="54.0" prefHeight="30.0" prefWidth="136.0" promptText="Person" />
      <Label layoutX="500.0" layoutY="30.0" prefHeight="18.0" prefWidth="114.0" text="Add production:">
         <font>
            <Font name="Ebrima Bold" size="14.0" />
         </font>
      </Label>
      <TextField fx:id="setOccupationBox" layoutX="489.0" layoutY="54.0" prefHeight="30.0" prefWidth="136.0" promptText="Occupation" />
      <TextField fx:id="setTitleBox" layoutX="345.0" layoutY="54.0" prefHeight="30.0" prefWidth="136.0" promptText="Title" />
   </children>
</AnchorPane>

错误:(对于3条CellProperty行中的每一行都会发生此错误,这只是1条,但是它们几乎完全相同)。

Apr 19,2020 7:20:12 PM javafx.scene.control.cell.PropertyValueFactory getcellDataReflectively
WARNING: Can not retrieve property 'title' in PropertyValueFactory: javafx.scene.control.cell.PropertyValueFactory@210cabaf with provided class type: class org.application.credits
java.lang.RuntimeException: java.lang.IllegalaccessException: module javafx.base cannot access class org.application.credits (in module org.example) because module org.example does not open org.application to javafx.base
    at javafx.base/com.sun.javafx.property.PropertyReference.get(PropertyReference.java:176)
    at javafx.controls/javafx.scene.control.cell.PropertyValueFactory.getcellDataReflectively(PropertyValueFactory.java:184)
    at javafx.controls/javafx.scene.control.cell.PropertyValueFactory.call(PropertyValueFactory.java:154)
    at javafx.controls/javafx.scene.control.cell.PropertyValueFactory.call(PropertyValueFactory.java:133)
    at javafx.controls/javafx.scene.control.TableColumn.getcellObservableValue(TableColumn.java:593)
    at javafx.controls/javafx.scene.control.TableColumn.getcellObservableValue(TableColumn.java:578)
    at javafx.controls/javafx.scene.control.TableCell.updateItem(TableCell.java:646)
    at javafx.controls/javafx.scene.control.TableCell.indexChanged(TableCell.java:469)
    at javafx.controls/javafx.scene.control.IndexedCell.updateIndex(IndexedCell.java:120)
    at javafx.controls/javafx.scene.control.skin.TableRowSkinBase.updateCells(TableRowSkinBase.java:539)
    at javafx.controls/javafx.scene.control.skin.TableRowSkinBase.<init>(TableRowSkinBase.java:159)
    at javafx.controls/javafx.scene.control.skin.TableRowSkin.<init>(TableRowSkin.java:89)
    at javafx.controls/javafx.scene.control.TableRow.createDefaultSkin(TableRow.java:213)
    at javafx.controls/javafx.scene.control.Control.doProcessCSS(Control.java:897)
    at javafx.controls/javafx.scene.control.Control$1.doProcessCSS(Control.java:89)
    at javafx.controls/com.sun.javafx.scene.control.ControlHelper.processCSSImpl(ControlHelper.java:67)
    at javafx.graphics/com.sun.javafx.scene.NodeHelper.processCSS(NodeHelper.java:145)
    at javafx.graphics/javafx.scene.Node.processCSS(Node.java:9540)
    at javafx.graphics/javafx.scene.Node.applyCss(Node.java:9627)
    at javafx.controls/javafx.scene.control.skin.VirtualFlow.setCellIndex(VirtualFlow.java:1749)
    at javafx.controls/javafx.scene.control.skin.VirtualFlow.getcell(VirtualFlow.java:1726)
    at javafx.controls/javafx.scene.control.skin.VirtualFlow.getcellLength(VirtualFlow.java:1852)
    at javafx.controls/javafx.scene.control.skin.VirtualFlow.computeViewportOffset(VirtualFlow.java:2755)
    at javafx.controls/javafx.scene.control.skin.VirtualFlow.layoutChildren(VirtualFlow.java:1245)
    at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1206)
    at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1213)
    at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1213)
    at javafx.graphics/javafx.scene.Scene.doLayoutPass(Scene.java:576)
    at javafx.graphics/javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2482)
    at javafx.graphics/com.sun.javafx.tk.Toolkit.lambda$runPulse$2(Toolkit.java:412)
    at java.base/java.security.accessController.doPrivileged(accessController.java:391)
    at javafx.graphics/com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:411)
    at javafx.graphics/com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:438)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:563)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:543)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromqueue(QuantumToolkit.java:536)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11(QuantumToolkit.java:342)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
    at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: java.lang.IllegalaccessException: module javafx.base cannot access class org.application.credits (in module org.example) because module org.example does not open org.application to javafx.base
    at javafx.base/com.sun.javafx.property.MethodHelper.invoke(MethodHelper.java:69)
    at javafx.base/com.sun.javafx.property.PropertyReference.get(PropertyReference.java:174)
    ... 40 more
zwm454 回答:JavaFX setCellValueFactory无法检索属性IllegalAcessException

出现异常是因为PropertyValueFactory使用反射来访问模型类Credits中的方法调用。由于您的模块尚未打开,因此无法访问javafx.base模块,因此您将获得发布的IllegalAccessException

您可以通过在module-info.java文件中添加以下内容来解决此问题:

opens org.application to javafx.base ;

也许更好的方法是避免使用PropertyValueFactory。该类的确是设计好的,因为在Java 8和lambda表达式之前,创建CellValueFactory只是为了访问模型类中的属性非常麻烦。随着Java 8中lambda表达式的出现,情况已不再如此,使用lambda表达式代替反射式PropertyValueFactory可能会提供更好的性能,并且更重要的是,它提供了编译时检查。

首先(无论如何,您都应该这样做),将属性访问器方法添加到您的Credits类中。按照您当前的班级情况,您可以创建StringProperty实例,但是没有访问它们的方法(只有访问其内容的方法)。因此,如果您致电,例如,您的表格将不会动态更新已显示的setTitle()实例上的Credits。您只需要添加

public class Credits {

    // all existing code...

    public StringProperty titleProperty() {
        return title ;
    }

    public StringProperty occupationProperty() {
        return occupation ;
    }

    public StringProperty personProperty() {
        return person ;
    }

}

现在,您可以直接在Credits类中引用属性:

title.setCellValueFactory(cellData -> cellData.getValue().titleProperty());

,其他列也类似。除了其他好处(主要是在编译时检查该属性是否确实存在)之外,这还避免了将Credits类反射地暴露给javafx.base模块的需要。

本文链接:https://www.f2er.com/2406345.html

大家都在问