001 /*
002 GRANITE DATA SERVICES
003 Copyright (C) 2012 GRANITE DATA SERVICES S.A.S.
004
005 This file is part of Granite Data Services.
006
007 Granite Data Services is free software; you can redistribute it and/or modify
008 it under the terms of the GNU Library General Public License as published by
009 the Free Software Foundation; either version 2 of the License, or (at your
010 option) any later version.
011
012 Granite Data Services is distributed in the hope that it will be useful, but
013 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015 for more details.
016
017 You should have received a copy of the GNU Library General Public License
018 along with this library; if not, see <http://www.gnu.org/licenses/>.
019 */
020
021 package org.granite.client.tide.collections.javafx;
022
023 import java.util.ArrayList;
024 import java.util.Collection;
025 import java.util.List;
026
027 import javax.annotation.PreDestroy;
028
029 import javafx.beans.InvalidationListener;
030 import javafx.collections.FXCollections;
031 import javafx.collections.ListChangeListener;
032 import javafx.collections.ObservableList;
033
034 import org.granite.client.tide.collections.AbstractPagedCollection;
035 import org.granite.client.tide.server.TideRpcEvent;
036 import org.granite.client.util.javafx.ListListenerHelper;
037 import org.granite.client.util.javafx.ListenerHelper;
038
039 /**
040 * @author William DRAI
041 */
042 public abstract class PagedCollection<E> extends AbstractPagedCollection<E> implements ObservableList<E> {
043
044 private List<E> internalWrappedList = new ArrayList<E>();
045 protected ObservableList<E> wrappedList;
046
047 private ListenerHelper<PageChangeListener<E>> pageChangeHelper = new ListenerHelper<PageChangeListener<E>>(PageChangeListener.class);
048
049
050 @Override
051 protected List<E> getInternalWrappedList() {
052 return internalWrappedList;
053 }
054
055 @Override
056 protected List<E> getWrappedList() {
057 return wrappedList;
058 }
059
060
061 public PagedCollection() {
062 super();
063
064 wrappedList = FXCollections.observableList(internalWrappedList);
065 wrappedList.addListener(new WrappedListListChangeListener());
066 }
067
068
069 @Override
070 public boolean setAll(Collection<? extends E> coll) {
071 if (!initializing)
072 return fullRefresh();
073 return false;
074 }
075
076
077 @Override
078 @PreDestroy
079 public void clear() {
080 helper.clear();
081 pageChangeHelper.clear();
082 super.clear();
083 }
084
085
086 private ListListenerHelper<E> helper = new ListListenerHelper<E>();
087
088 public void addListener(ListChangeListener<? super E> listener) {
089 helper.addListener(listener);
090 }
091
092 public void removeListener(ListChangeListener<? super E> listener) {
093 helper.removeListener(listener);
094 }
095
096 public void addListener(InvalidationListener listener) {
097 helper.addListener(listener);
098 }
099
100 public void removeListener(InvalidationListener listener) {
101 helper.removeListener(listener);
102 }
103
104 public void addListener(PageChangeListener<E> listener) {
105 pageChangeHelper.addListener(listener);
106 }
107
108 public void removeListener(PageChangeListener<E> listener) {
109 pageChangeHelper.removeListener(listener);
110 }
111
112 public void firePageChange(TideRpcEvent event) {
113 fireItemsUpdated(0, this.last-this.first);
114 pageChangeHelper.fireEvent(this, event);
115 }
116
117
118 public class WrappedListListChangeListener implements ListChangeListener<E> {
119 @Override
120 public void onChanged(ListChangeListener.Change<? extends E> change) {
121 ListChangeWrapper wrappedChange = new ListChangeWrapper(wrappedList, change);
122 helper.fireValueChangedEvent(wrappedChange);
123 }
124 }
125
126 public void fireItemsUpdated(final int from, final int to) {
127 ListChangeListener.Change<E> change = new ListChangeListener.Change<E>(wrappedList) {
128 @Override
129 public int getFrom() {
130 return first+from;
131 }
132
133 @Override
134 public int getTo() {
135 return first+to;
136 }
137
138 @Override
139 public boolean wasUpdated() {
140 return true;
141 }
142
143 @Override
144 protected int[] getPermutation() {
145 return EMPTY_PERMUTATION;
146 }
147
148 @Override
149 public List<E> getRemoved() {
150 return null;
151 }
152
153 @Override
154 public boolean next() {
155 return false;
156 }
157
158 @Override
159 public void reset() {
160 }
161 };
162 helper.fireValueChangedEvent(change);
163 }
164
165 private static final int[] EMPTY_PERMUTATION = new int[0];
166
167 public class ListChangeWrapper extends ListChangeListener.Change<E> {
168 private final ListChangeListener.Change<? extends E> wrappedChange;
169
170 public ListChangeWrapper(ObservableList<E> list, ListChangeListener.Change<? extends E> wrappedChange) {
171 super(list);
172 this.wrappedChange = wrappedChange;
173 }
174
175 @Override
176 public int getAddedSize() {
177 return wrappedChange.getAddedSize();
178 }
179
180 @SuppressWarnings("unchecked")
181 @Override
182 public List<E> getAddedSubList() {
183 return (List<E>)wrappedChange.getAddedSubList();
184 }
185
186 @Override
187 public int getRemovedSize() {
188 return wrappedChange.getRemovedSize();
189 }
190
191 @Override
192 public boolean wasAdded() {
193 return wrappedChange.wasAdded();
194 }
195
196 @Override
197 public boolean wasPermutated() {
198 return wrappedChange.wasPermutated();
199 }
200
201 @Override
202 public boolean wasRemoved() {
203 return wrappedChange.wasRemoved();
204 }
205
206 @Override
207 public boolean wasReplaced() {
208 return wrappedChange.wasReplaced();
209 }
210
211 @Override
212 public boolean wasUpdated() {
213 return wrappedChange.wasUpdated();
214 }
215
216 @Override
217 public int getFrom() {
218 int from = wrappedChange.getFrom();
219 return from+first;
220 }
221
222 @Override
223 public int getTo() {
224 int to = wrappedChange.getTo();
225 return to+first;
226 }
227
228 @Override
229 protected int[] getPermutation() {
230 return EMPTY_PERMUTATION;
231 }
232
233 @Override
234 public int getPermutation(int num) {
235 return wrappedChange.getPermutation(num);
236 }
237
238 @SuppressWarnings("unchecked")
239 @Override
240 public List<E> getRemoved() {
241 return (List<E>)wrappedChange.getRemoved();
242 }
243
244 @Override
245 public boolean next() {
246 return wrappedChange.next();
247 }
248
249 @Override
250 public void reset() {
251 wrappedChange.reset();
252 }
253 }
254
255
256 @Override
257 public Object[] toArray() {
258 return wrappedList.toArray();
259 }
260
261 @Override
262 public <T> T[] toArray(T[] a) {
263 return wrappedList.toArray(a);
264 }
265
266 @Override
267 public boolean add(E e) {
268 throw new UnsupportedOperationException();
269 }
270
271 @Override
272 public void add(int index, E element) {
273 throw new UnsupportedOperationException();
274 }
275
276 @Override
277 public boolean addAll(Collection<? extends E> c) {
278 throw new UnsupportedOperationException();
279 }
280
281 @Override
282 public boolean addAll(int index, Collection<? extends E> c) {
283 throw new UnsupportedOperationException();
284 }
285
286 @Override
287 public boolean addAll(E... arg0) {
288 throw new UnsupportedOperationException();
289 }
290
291 @Override
292 public boolean remove(Object o) {
293 throw new UnsupportedOperationException();
294 }
295
296 @Override
297 public E remove(int index) {
298 throw new UnsupportedOperationException();
299 }
300
301 @Override
302 public boolean removeAll(Collection<?> c) {
303 throw new UnsupportedOperationException();
304 }
305
306 @Override
307 public void remove(int arg0, int arg1) {
308 throw new UnsupportedOperationException();
309 }
310
311 @Override
312 public boolean removeAll(E... arg0) {
313 throw new UnsupportedOperationException();
314 }
315
316 @Override
317 public boolean retainAll(E... arg0) {
318 throw new UnsupportedOperationException();
319 }
320
321 @Override
322 public boolean setAll(E... arg0) {
323 throw new UnsupportedOperationException();
324 }
325
326 @Override
327 public boolean retainAll(Collection<?> c) {
328 throw new UnsupportedOperationException();
329 }
330
331 @Override
332 public E set(int index, E element) {
333 throw new UnsupportedOperationException();
334 }
335
336 @Override
337 public List<E> subList(int fromIndex, int toIndex) {
338 throw new UnsupportedOperationException();
339 }
340 }