JavaFX setCellValueFactory не может получить свойство IllegalAcessException - PullRequest
0 голосов
/ 19 апреля 2020

Я проверил не менее 20 других тем на эту тему и попытался отладить это как можно лучше, но понятия не имею, почему это не сработает. Я хочу, чтобы мой addButton добавлял мои данные в мой TableView из TextBoxes при нажатии кнопки.

Мой класс данных:

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);
    }

}

Фрагмент важной части моего класса контроллера

    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);
    }

f xml Файл:

<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

1 Ответ

1 голос
/ 19 апреля 2020

Исключение возникает потому, что PropertyValueFactory использует отражение для доступа к вызовам методов в классе вашей модели Credits. Поскольку ваш модуль не открыт для такого доступа к модулю javafx.base, вы получите отправленный вами IllegalAccessException.

Это можно исправить, добавив в файл module-info.java строку, подобную следующей:

opens org.application to javafx.base ;

Возможно, лучший подход - избегать использования PropertyValueFactory. Этот класс был действительно разработан, потому что до Java 8 и лямбда-выражений создание CellValueFactory просто для доступа к свойству в модельном классе было довольно громоздким. С появлением лямбда-выражения в Java 8 это уже не так, и использование лямбда-выражения вместо отражающего 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...