2013-09-03 32 views
5

Mã này ném ra một UnsupportedOperationException, như tôi mong đợi nó kể từ khi nó chỉ đọc.ReadOnlyListProperty JavaFX không chỉ đọc?

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

Tuy nhiên, mã này thì không.

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

Đây có phải là lỗi hay tôi chỉ không hiểu điều gì đó?

Trả lời

8

Kỳ vọng ban đầu là sai - đối với các ví dụ được cung cấp. UnsupportedOperationException xảy ra vì một lý do khác và không phải vì danh sách "chỉ đọc" được "ghi". Vẫn có thể có danh sách "chỉ đọc". Tôi hy vọng câu trả lời dưới đây sẽ giúp làm rõ.

Câu trả lời cần được xem xét trong hai phần. Một: Ngoại lệ ListProperty và hai: Danh sách chỉ đọc.

1) Ví dụ về ListProperty không thành công do không có danh sách nào được gán cho thuộc tính.

Ví dụ, đơn giản hóa này cũng ném ngoại lệ. Lưu ý rằng bất kỳ "read-only" khía cạnh được loại bỏ:

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

Điều này có thể được sửa chữa với:

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

Nếu chúng ta thay đổi ví dụ ban đầu một cách tương tự thì không phải các ListProperty cũng không phải là ví dụ ObservableList sẽ ném một ngoại lệ, đó không phải là những gì OP muốn hoặc mong đợi.

2) Phần thứ hai hỏi tại sao một phần tử có thể được thêm vào danh sách chỉ đọc. Sử dụng FXCollections.unmodifiableObservableList để tạo ra các danh sách chỉ đọc sẽ ném UnsupportedOperationException như mong đợi:

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

Nhưng điều này không trả lời câu hỏi tại sao không phải là ReadOnlyListWrapper/tài sản làm điều này?

Hãy xử lý trước thuộc tính. ListProperty bật giá trị để thay đổi, tức là nó cho phép bạn chỉ định một danh sách khác cho thuộc tính. ReadOnlyListProperty không cho phép điều này, tức là khi danh sách được gán, nó vẫn là đối tượng danh sách đó. Nội dung của danh sách vẫn có thể thay đổi. Ví dụ bên dưới không có ý nghĩa gì với ReadOnlyListProperty:

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

Vì vậy chỉ đọc chỉ đề cập đến Thuộc tính chứ không phải Danh sách.

Cuối cùng - ReadOnlyListWrapper - như tài liệu API nói "Lớp này cung cấp một lớp tiện lợi để xác định thuộc tính chỉ đọc. Nó tạo hai thuộc tính được đồng bộ hóa. Một thuộc tính là chỉ đọc và có thể được chuyển cho người dùng bên ngoài. tài sản khác là đọc và ghi và chỉ nên sử dụng nội bộ. "

+0

Cảm ơn phản hồi chi tiết. Kể từ khi tôi đăng bài này, tôi đã dành nhiều thời gian hơn với FX và đã hiểu những gì bạn đã đăng. Tài liệu vẫn còn hơi mỏng, nhưng như bạn đã chỉ ra tôi có thể tìm thấy ít nhất một phần câu trả lời của tôi bằng cách đọc tài liệu API. –

Các vấn đề liên quan