Spec-Zone .ru
спецификации, руководства, описания, API
|
001/* 002 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. Oracle designates this 008 * particular file as subject to the "Classpath" exception as provided 009 * by Oracle in the LICENSE file that accompanied this code. 010 * 011 * This code is distributed in the hope that it will be useful, but WITHOUT 012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 014 * version 2 for more details (a copy is included in the LICENSE file that 015 * accompanied this code). 016 * 017 * You should have received a copy of the GNU General Public License version 018 * 2 along with this work; if not, write to the Free Software Foundation, 019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 020 * 021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 022 * or visit www.oracle.com if you need additional information or have any 023 * questions. 024 */ 025 026package javafx.beans.binding; 027 028import com.sun.javafx.binding.StringFormatter; 029import com.sun.javafx.collections.annotations.ReturnsUnmodifiableCollection; 030import javafx.beans.property.ReadOnlyBooleanProperty; 031import javafx.beans.property.ReadOnlyIntegerProperty; 032import javafx.beans.value.ObservableIntegerValue; 033import javafx.beans.value.ObservableListValue; 034import javafx.collections.FXCollections; 035import javafx.collections.ObservableList; 036 037import java.util.Collection; 038import java.util.Iterator; 039import java.util.List; 040import java.util.ListIterator; 041 042/** 043 * A {@code ListExpression} is a 044 * {@link javafx.beans.value.ObservableListValue} plus additional convenience 045 * methods to generate bindings in a fluent style. 046 * <p> 047 * A concrete sub-class of {@code ListExpression} has to implement the method 048 * {@link javafx.beans.value.ObservableListValue#get()}, which provides the 049 * actual value of this expression. 050 * <p> 051 * If the wrapped list of a {@code ListExpression} is {@code null}, all methods implementing the {@code List} 052 * interface will behave as if they were applied to an immutable empty list. 053 * 054 * @param <E> the type of the {@code List} elements. 055 */ 056public abstract class ListExpression<E> implements ObservableListValue<E> { 057 058 private static final ObservableList EMPTY_LIST = FXCollections.emptyObservableList(); 059 060 @Override 061 public ObservableList<E> getValue() { 062 return get(); 063 } 064 065 /** 066 * Returns a {@code ListExpression} that wraps a 067 * {@link javafx.beans.value.ObservableListValue}. If the 068 * {@code ObservableListValue} is already a {@code ListExpression}, it 069 * will be returned. Otherwise a new 070 * {@link javafx.beans.binding.ListBinding} is created that is bound to 071 * the {@code ObservableListValue}. 072 * 073 * @param value 074 * The source {@code ObservableListValue} 075 * @return A {@code ListExpression} that wraps the 076 * {@code ObservableListValue} if necessary 077 * @throws NullPointerException 078 * if {@code value} is {@code null} 079 */ 080 public static <E> ListExpression<E> listExpression(final ObservableListValue<E> value) { 081 if (value == null) { 082 throw new NullPointerException("List must be specified."); 083 } 084 return value instanceof ListExpression ? (ListExpression<E>) value 085 : new ListBinding<E>() { 086 { 087 super.bind(value); 088 } 089 090 @Override 091 public void dispose() { 092 super.unbind(value); 093 } 094 095 @Override 096 protected ObservableList<E> computeValue() { 097 return value.get(); 098 } 099 100 @Override 101 @ReturnsUnmodifiableCollection 102 public ObservableList<ObservableListValue<E>> getDependencies() { 103 return FXCollections.singletonObservableList(value); 104 } 105 }; 106 } 107 108 /** 109 * The size of the list 110 */ 111 public int getSize() { 112 return size(); 113 } 114 public abstract ReadOnlyIntegerProperty sizeProperty(); 115 116 /** 117 * A boolean property that is {@code true}, if the list is empty. 118 */ 119 public abstract ReadOnlyBooleanProperty emptyProperty(); 120 121 /** 122 * Creates a new {@link ObjectBinding} that contains the element at the specified position. 123 * If {@code index} points behind the list, the {@code ObjectBinding} contains {@code null}. 124 * 125 * @param index the index of the element 126 * @return the {@code ObjectBinding} 127 * @throws IllegalArgumentException if {@code index < 0} 128 */ 129 public ObjectBinding<E> valueAt(int index) { 130 return Bindings.valueAt(this, index); 131 } 132 133 /** 134 * Creates a new {@link ObjectBinding} that contains the element at the specified position. 135 * If {@code index} points outside of the list, the {@code ObjectBinding} contains {@code null}. 136 * 137 * @param index the index of the element 138 * @return the {@code ObjectBinding} 139 * @throws NullPointerException if {@code index} is {@code null} 140 */ 141 public ObjectBinding<E> valueAt(ObservableIntegerValue index) { 142 return Bindings.valueAt(this, index); 143 } 144 145 /** 146 * Creates a new {@link BooleanBinding} that holds {@code true} if this list is equal to 147 * another {@link javafx.collections.ObservableList}. 148 * 149 * @param other 150 * the other {@code ObservableList} 151 * @return the new {@code BooleanBinding} 152 * @throws NullPointerException 153 * if {@code other} is {@code null} 154 */ 155 public BooleanBinding isEqualTo(final ObservableList<?> other) { 156 return Bindings.equal(this, other); 157 } 158 159 /** 160 * Creates a new {@link BooleanBinding} that holds {@code true} if this list is not equal to 161 * another {@link javafx.collections.ObservableList}. 162 * 163 * @param other 164 * the other {@code ObservableList} 165 * @return the new {@code BooleanBinding} 166 * @throws NullPointerException 167 * if {@code other} is {@code null} 168 */ 169 public BooleanBinding isNotEqualTo(final ObservableList<?> other) { 170 return Bindings.notEqual(this, other); 171 } 172 173 /** 174 * Creates a new {@link BooleanBinding} that holds {@code true} if the wrapped list is {@code null}. 175 * 176 * @return the new {@code BooleanBinding} 177 */ 178 public BooleanBinding isNull() { 179 return Bindings.isNull(this); 180 } 181 182 /** 183 * Creates a new {@link BooleanBinding} that holds {@code true} if the wrapped list is not {@code null}. 184 * 185 * @return the new {@code BooleanBinding} 186 */ 187 public BooleanBinding isNotNull() { 188 return Bindings.isNotNull(this); 189 } 190 191 /** 192 * Creates a {@link javafx.beans.binding.StringBinding} that holds the value 193 * of the {@code ListExpression} turned into a {@code String}. If the 194 * value of this {@code ListExpression} changes, the value of the 195 * {@code StringBinding} will be updated automatically. 196 * 197 * @return the new {@code StringBinding} 198 */ 199 public StringBinding asString() { 200 return (StringBinding) StringFormatter.convert(this); 201 } 202 203 @Override 204 public int size() { 205 final ObservableList<E> list = get(); 206 return (list == null)? EMPTY_LIST.size() : list.size(); 207 } 208 209 @Override 210 public boolean isEmpty() { 211 final ObservableList<E> list = get(); 212 return (list == null)? EMPTY_LIST.isEmpty() : list.isEmpty(); 213 } 214 215 @Override 216 public boolean contains(Object obj) { 217 final ObservableList<E> list = get(); 218 return (list == null)? EMPTY_LIST.contains(obj) : list.contains(obj); 219 } 220 221 @Override 222 public Iterator<E> iterator() { 223 final ObservableList<E> list = get(); 224 return (list == null)? EMPTY_LIST.iterator() : list.iterator(); 225 } 226 227 @Override 228 public Object[] toArray() { 229 final ObservableList<E> list = get(); 230 return (list == null)? EMPTY_LIST.toArray() : list.toArray(); 231 } 232 233 @Override 234 public <T> T[] toArray(T[] array) { 235 final ObservableList<E> list = get(); 236 return (list == null)? (T[]) EMPTY_LIST.toArray(array) : list.toArray(array); 237 } 238 239 @Override 240 public boolean add(E element) { 241 final ObservableList<E> list = get(); 242 return (list == null)? EMPTY_LIST.add(element) : list.add(element); 243 } 244 245 @Override 246 public boolean remove(Object obj) { 247 final ObservableList<E> list = get(); 248 return (list == null)? EMPTY_LIST.remove(obj) : list.remove(obj); 249 } 250 251 @Override 252 public boolean containsAll(Collection<?> objects) { 253 final ObservableList<E> list = get(); 254 return (list == null)? EMPTY_LIST.contains(objects) : list.containsAll(objects); 255 } 256 257 @Override 258 public boolean addAll(Collection<? extends E> elements) { 259 final ObservableList<E> list = get(); 260 return (list == null)? EMPTY_LIST.addAll(elements) : list.addAll(elements); 261 } 262 263 @Override 264 public boolean addAll(int i, Collection<? extends E> elements) { 265 final ObservableList<E> list = get(); 266 return (list == null)? EMPTY_LIST.addAll(i, elements) : list.addAll(i, elements); 267 } 268 269 @Override 270 public boolean removeAll(Collection<?> objects) { 271 final ObservableList<E> list = get(); 272 return (list == null)? EMPTY_LIST.removeAll(objects) : list.removeAll(objects); 273 } 274 275 @Override 276 public boolean retainAll(Collection<?> objects) { 277 final ObservableList<E> list = get(); 278 return (list == null)? EMPTY_LIST.retainAll(objects) : list.retainAll(objects); 279 } 280 281 @Override 282 public void clear() { 283 final ObservableList<E> list = get(); 284 if (list == null) { 285 EMPTY_LIST.clear(); 286 } else { 287 list.clear(); 288 } 289 } 290 291 @Override 292 public E get(int i) { 293 final ObservableList<E> list = get(); 294 return (list == null)? (E) EMPTY_LIST.get(i) : list.get(i); 295 } 296 297 @Override 298 public E set(int i, E element) { 299 final ObservableList<E> list = get(); 300 return (list == null)? (E) EMPTY_LIST.set(i, element) : list.set(i, element); 301 } 302 303 @Override 304 public void add(int i, E element) { 305 final ObservableList<E> list = get(); 306 if (list == null) { 307 EMPTY_LIST.add(i, element); 308 } else { 309 list.add(i, element); 310 } 311 } 312 313 @Override 314 public E remove(int i) { 315 final ObservableList<E> list = get(); 316 return (list == null)? (E) EMPTY_LIST.remove(i) : list.remove(i); 317 } 318 319 @Override 320 public int indexOf(Object obj) { 321 final ObservableList<E> list = get(); 322 return (list == null)? EMPTY_LIST.indexOf(obj) : list.indexOf(obj); 323 } 324 325 @Override 326 public int lastIndexOf(Object obj) { 327 final ObservableList<E> list = get(); 328 return (list == null)? EMPTY_LIST.lastIndexOf(obj) : list.lastIndexOf(obj); 329 } 330 331 @Override 332 public ListIterator<E> listIterator() { 333 final ObservableList<E> list = get(); 334 return (list == null)? EMPTY_LIST.listIterator() : list.listIterator(); 335 } 336 337 @Override 338 public ListIterator<E> listIterator(int i) { 339 final ObservableList<E> list = get(); 340 return (list == null)? EMPTY_LIST.listIterator(i) : list.listIterator(i); 341 } 342 343 @Override 344 public List<E> subList(int from, int to) { 345 final ObservableList<E> list = get(); 346 return (list == null)? EMPTY_LIST.subList(from, to) : list.subList(from, to); 347 } 348 349 @Override 350 public boolean addAll(E... elements) { 351 final ObservableList<E> list = get(); 352 return (list == null)? EMPTY_LIST.addAll(elements) : list.addAll(elements); 353 } 354 355 @Override 356 public boolean setAll(E... elements) { 357 final ObservableList<E> list = get(); 358 return (list == null)? EMPTY_LIST.setAll(elements) : list.setAll(elements); 359 } 360 361 @Override 362 public boolean setAll(Collection<? extends E> elements) { 363 final ObservableList<E> list = get(); 364 return (list == null)? EMPTY_LIST.setAll(elements) : list.setAll(elements); 365 } 366 367 @Override 368 public boolean removeAll(E... elements) { 369 final ObservableList<E> list = get(); 370 return (list == null)? EMPTY_LIST.removeAll(elements) : list.removeAll(elements); 371 } 372 373 @Override 374 public boolean retainAll(E... elements) { 375 final ObservableList<E> list = get(); 376 return (list == null)? EMPTY_LIST.retainAll(elements) : list.retainAll(elements); 377 } 378 379 @Override 380 public void remove(int from, int to) { 381 final ObservableList<E> list = get(); 382 if (list == null) { 383 EMPTY_LIST.remove(from, to); 384 } else { 385 list.remove(from, to); 386 } 387 } 388 389}