JavaFX PropertyValueFactory не может получить свойство из класса, расположенного в разных пакетах - PullRequest
1 голос
/ 15 марта 2019

У меня есть два пакета, один для объектов и другой для создания графического интерфейса. Я пытаюсь создать TableView в JavaFX, и мне нужно использовать PropertyValuesFactory<>(property), чтобы получить значение объекта. Таким образом, у меня есть ошибка, при которой, если я помещу класс Person и GUI в один и тот же пакет, все будет работать нормально, но когда класс Person помещен в пакет объектов, все идет плохо, и я получаю эту ошибку:

WARNING: Can not retrieve property 'name' in PropertyValueFactory: javafx.scene.control.cell.PropertyValueFactory@6771b7fb with provided class type: class uni.rest.objects.Person
    java.lang.RuntimeException: java.lang.IllegalAccessException: module javafx.base cannot access class uni.rest.objects.Person (in module main) because module main does not open uni.rest.objects to javafx.base

Это также строка кода, где происходит ошибка:

person_column.setCellValueFactory(new PropertyValueFactory<>("name"));

Итак, я предполагаю, что местоположение значения свойства может быть изменено ... Буду признателен за любую помощь.

1 Ответ

3 голосов
/ 15 марта 2019

Класс PropertyValueFactory использует отражение для доступа к свойствам класса модели.Модульная система, добавленная в Java 9, добавляет большую инкапсуляцию, которая предотвращает рефлексивный доступ модулей к другим модулям, если только не дано разрешение директивами в module-info.java.

В документации из PropertyValueFactory указано, что вам нужноЧто делать, если развертывание приложения выполняется в виде модуля:

Развертывание приложения в виде модуля

Если указанный класс находится в именованном модуле, он долженбыть отражательно доступным для модуля javafx.base.Класс является рефлексивно доступным, если модуль открывает содержащий пакет хотя бы для модуля javafx.base.В противном случае метод call(TableColumn.CellDataFeatures) запишет предупреждение и вернет null.

Например, если класс Person находится в пакете com.foo в модуле foo.appmodule-info.java может выглядеть следующим образом:

module foo.app {
    opens com.foo to javafx.base;
}

В качестве альтернативы, класс является отражательно доступным, если модуль экспортирует содержащий пакет безоговорочно


Другой вариант - отказаться от PropertyValueFactory и использовать пользовательский Callback.PropertyValueFactory было больше удобством, когда лямбды не были чем-то особенным;перед лямбдами, если бы кто-то хотел использовать пользовательский Callback, он должен был бы каждый раз создавать анонимный класс, который был бы многословным.Однако, поскольку лямбда-выражения можно сделать:

person_column.setCellValueFactory(features -> features.getValue().nameProperty());

Очевидно, что это работает лучше всего, если модель предоставляет свойство JavaFX.Преимущества пользовательского Callback включают избегание отражения и безопасность типов.

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