2013-09-03 2 views
5

Этот код генерирует исключение UnsupportedOperationException, как и ожидалось, поскольку оно доступно только для чтения.JavaFX ReadOnlyListProperty не доступен для чтения?

ListProperty<String> lp = new SimpleListProperty<String>(); 
ReadOnlyListWrapper<String> rolw = new ReadOnlyListWrapper<String>(lp); 
ReadOnlyListProperty<String> rolp = rolw.getReadOnlyProperty(); 
rolp.add("element"); 

Однако этот код не является.

ObservableList<String> ol = FXCollections.observableArrayList(); 
ReadOnlyListWrapper<String> rolw = new ReadOnlyListWrapper<String>(ol); 
ReadOnlyListProperty<String> rolp = rolw.getReadOnlyProperty(); 
rolp.add("element"); 

Это ошибка, или я что-то не понимаю?

ответ

8

Исходное ожидание неверно - для приведенных примеров. Исключение UnsupportedOperationException происходит по другой причине, а не потому, что «список« только для чтения »« записывается »в. Все еще возможно иметь списки «только для чтения». Надеюсь, ответ ниже поможет прояснить.

Ответ должен быть рассмотрен в двух частях. Один: исключение ListProperty и два: только для чтения.

1) Пример ListProperty завершился неудачно, потому что для свойства не было присвоено списка.

Этот упрощенный пример также выдает исключение. Обратите внимание, что любые «только для чтения» аспекты будут удалены:

ListProperty<String> lp = new SimpleListProperty<>(); 
lp.add("element"); 

Это может быть исправлено с:

ObservableList ol = FXCollections.observableArrayList(); 
ListProperty<String> lp = new SimpleListProperty<>(); 
lp.setValue(ol); 
lp.add("element"); 

Если мы изменим исходный пример таким же образом, то ни ListProperty, ни примеров ObservableList будет генерировать исключение, которое не было тем, чего хотел или ожидал ОП.

2) Вторая часть спрашивает, почему элемент может быть добавлен в список только для чтения. Использование FXCollections.unmodifiableObservableList, чтобы создать список только для чтения отбросит UnsupportedOperationException, как и ожидалось:

ObservableList<String> ol = FXCollections.observableArrayList(); 
ObservableList<String> uol = FXCollections.unmodifiableObservableList(ol); 
uol.add("element"); 

Но это не дает ответа на вопрос, почему делать не ReadOnlyListWrapper/недвижимости это?

Сдача в аренду недвижимости. ListProperty позволяет изменить значение , то есть оно позволяет назначить другой список этому свойству. ReadOnlyListProperty не разрешает это, то есть после того, как список назначен, он остается этим объектом списка. Содержимое списка все равно может измениться. Приведенный ниже пример не имеет смысла с ReadOnlyListProperty:

ObservableList<String> ol1 = FXCollections.observableArrayList(); 
ObservableList<String> ol2 = FXCollections.observableArrayList(); 
ListProperty<String> lp = new SimpleListProperty<>(ol1); 
lp.setValue(ol2); 

Так только для чтения относится к собственности, а не список.

Окончательно - ReadOnlyListWrapper - как указано в документации API: «Этот класс предоставляет удобный класс для определения свойств только для чтения. Он создает два свойства, которые синхронизированы. Одно свойство доступно только для чтения и может передаваться внешним пользователям. другое свойство доступно для чтения и записи и должно использоваться только внутри страны ».

+0

Спасибо за подробный ответ. Поскольку я опубликовал это, я проводил больше времени с FX и понял, что вы разместили. Документация по-прежнему немного тонкая, но, как вы указали, я мог найти хотя бы часть своего ответа, прочитав документ API. –

Смежные вопросы