< prev index next >

modules/javafx.base/src/main/java/javafx/collections/FXCollections.java

Print this page




  72  * therefore suitable for methods that require ObservableList on input.
  73  * <br><br>
  74  * The utility methods are here mainly for performance reasons. All methods are optimized in a way that
  75  * they yield only limited number of notifications. On the other hand, java.util.Collections methods
  76  * might call "modification methods" on an ObservableList multiple times, resulting in a number of notifications.
  77  *
  78  * @since JavaFX 2.0
  79  */
  80 public class FXCollections {
  81     /** Not to be instantiated. */
  82     private FXCollections() { }
  83 
  84     /**
  85      * Constructs an ObservableList that is backed by the specified list.
  86      * Mutation operations on the ObservableList instance will be reported
  87      * to observers that have registered on that instance.<br>
  88      * Note that mutation operations made directly to the underlying list are
  89      * <em>not</em> reported to observers of any ObservableList that
  90      * wraps it.
  91      *

  92      * @param list a concrete List that backs this ObservableList
  93      * @return a newly created ObservableList
  94      */
  95     public static <E> ObservableList<E> observableList(List<E> list) {
  96         if (list == null) {
  97             throw new NullPointerException();
  98         }
  99         return list instanceof RandomAccess ? new ObservableListWrapper<E>(list) :
 100                 new ObservableSequentialListWrapper<E>(list);
 101     }
 102 
 103     /**
 104      * Constructs an ObservableList that is backed by the specified list.
 105      * Mutation operations on the ObservableList instance will be reported
 106      * to observers that have registered on that instance.<br>
 107      * Note that mutation operations made directly to the underlying list are
 108      * <em>not</em> reported to observers of any ObservableList that
 109      * wraps it.
 110      * <br>
 111      * This list also reports mutations of the elements in it by using <code>extractor</code>.
 112      * Observable objects returned by extractor (applied to each list element) are listened for changes
 113      * and transformed into "update" change of ListChangeListener.
 114      *

 115      * @param list a concrete List that backs this ObservableList
 116      * @param extractor element to Observable[] convertor
 117      * @since JavaFX 2.1
 118      * @return a newly created ObservableList
 119      */
 120     public static <E> ObservableList<E> observableList(List<E> list, Callback<E, Observable[]> extractor) {
 121         if (list == null || extractor == null) {
 122             throw new NullPointerException();
 123         }
 124         return list instanceof RandomAccess ? new ObservableListWrapper<E>(list, extractor) :
 125             new ObservableSequentialListWrapper<E>(list, extractor);
 126     }
 127 
 128     /**
 129      * Constructs an ObservableMap that is backed by the specified map.
 130      * Mutation operations on the ObservableMap instance will be reported
 131      * to observers that have registered on that instance.<br>
 132      * Note that mutation operations made directly to the underlying map are <em>not</em>
 133      * reported to observers of any ObservableMap that wraps it.


 134      * @param map a Map that backs this ObservableMap
 135      * @return a newly created ObservableMap
 136      */
 137     public static <K, V> ObservableMap<K, V> observableMap(Map<K, V> map) {
 138         if (map == null) {
 139             throw new NullPointerException();
 140         }
 141         return new ObservableMapWrapper<K, V>(map);
 142     }
 143 
 144     /**
 145      * Constructs an ObservableSet that is backed by the specified set.
 146      * Mutation operations on the ObservableSet instance will be reported
 147      * to observers that have registered on that instance.<br>
 148      * Note that mutation operations made directly to the underlying set are <em>not</em>
 149      * reported to observers of any ObservableSet that wraps it.

 150      * @param set a Set that backs this ObservableSet
 151      * @return a newly created ObservableSet
 152      * @since JavaFX 2.1
 153      */
 154     public static <E> ObservableSet<E> observableSet(Set<E> set) {
 155         if (set == null) {
 156             throw new NullPointerException();
 157         }
 158         return new ObservableSetWrapper<E>(set);
 159     }
 160 
 161     /**
 162      * Constructs an ObservableSet backed by a HashSet
 163      * that contains all the specified elements.

 164      * @param elements elements that will be added into returned ObservableSet
 165      * @return a newly created ObservableSet
 166      * @since JavaFX 2.1
 167      */
 168     public static <E> ObservableSet<E> observableSet(E... elements) {
 169         if (elements == null) {
 170             throw new NullPointerException();
 171         }
 172         Set<E> set = new HashSet<E>(elements.length);
 173         Collections.addAll(set, elements);
 174         return new ObservableSetWrapper<E>(set);
 175     }
 176 
 177     /**
 178      * Constructs a read-only interface to the specified ObservableMap. Only
 179      * mutation operations made to the underlying ObservableMap will be reported
 180      * to observers that have registered on the unmodifiable instance. This allows
 181      * clients to track changes in a Map but disallows the ability to modify it.


 182      * @param map an ObservableMap that is to be monitored by this interface
 183      * @return a newly created UnmodifiableObservableMap
 184      */
 185     public static <K, V> ObservableMap<K, V> unmodifiableObservableMap(ObservableMap<K, V> map) {
 186         if (map == null) {
 187             throw new NullPointerException();
 188         }
 189         return new com.sun.javafx.collections.UnmodifiableObservableMap<K, V>(map);
 190     }
 191 
 192     /**
 193      * Creates and returns a typesafe wrapper on top of provided observable map.


 194      * @param map an Observable map to be wrapped
 195      * @param keyType the type of key that {@code map} is permitted to hold
 196      * @param valueType the type of value that {@code map} is permitted to hold
 197      * @return a dynamically typesafe view of the specified map
 198      * @see Collections#checkedMap(java.util.Map, java.lang.Class)
 199      * @since JavaFX 8.0
 200      */
 201     public static <K, V> ObservableMap<K, V> checkedObservableMap(ObservableMap<K, V> map, Class<K> keyType, Class<V> valueType) {
 202         if (map == null || keyType == null || valueType == null) {
 203             throw new NullPointerException();
 204         }
 205         return new CheckedObservableMap<K, V>(map, keyType, valueType);
 206     }
 207 
 208     /**
 209      * Creates and returns a synchronized wrapper on top of provided observable map.


 210      * @param  map the map to be "wrapped" in a synchronized map.
 211      * @return A synchronized version of the observable map
 212      * @see Collections#synchronizedMap(java.util.Map)
 213      * @since JavaFX 8.0
 214      */
 215     public static <K, V> ObservableMap<K, V> synchronizedObservableMap(ObservableMap<K, V> map) {
 216         if (map == null) {
 217             throw new NullPointerException();
 218         }
 219         return new SynchronizedObservableMap<K, V>(map);
 220     }
 221 
 222     private static ObservableMap EMPTY_OBSERVABLE_MAP = new EmptyObservableMap();
 223 
 224     /**
 225      * Creates and empty unmodifiable observable map.


 226      * @return An empty unmodifiable observable map
 227      * @see Collections#emptyMap()
 228      * @since JavaFX 8.0
 229      */
 230     @SuppressWarnings("unchecked")
 231     public static <K, V> ObservableMap<K, V> emptyObservableMap() {
 232         return EMPTY_OBSERVABLE_MAP;
 233     }
 234 
 235     /**
 236      * Creates a new empty observable integer array.
 237      * @return a newly created ObservableIntegerArray
 238      * @since JavaFX 8.0
 239      */
 240     public static ObservableIntegerArray observableIntegerArray() {
 241         return new ObservableIntegerArrayImpl();
 242     }
 243 
 244     /**
 245      * Creates a new observable integer array with {@code values} set to it.


 278      * @since JavaFX 8.0
 279      */
 280     public static ObservableFloatArray observableFloatArray(float... values) {
 281         return new ObservableFloatArrayImpl(values);
 282     }
 283 
 284     /**
 285      * Creates a new observable float array with copy of elements in given
 286      * {@code array}.
 287      * @param array observable float array to copy
 288      * @return a newly created ObservableFloatArray
 289      * @since JavaFX 8.0
 290      */
 291     public static ObservableFloatArray observableFloatArray(ObservableFloatArray array) {
 292         return new ObservableFloatArrayImpl(array);
 293     }
 294 
 295     /**
 296      * Creates a new empty observable list that is backed by an arraylist.
 297      * @see #observableList(java.util.List)

 298      * @return a newly created ObservableList
 299      */
 300     @SuppressWarnings("unchecked")
 301     public static <E> ObservableList<E> observableArrayList() {
 302         return observableList(new ArrayList());
 303     }
 304 
 305     /**
 306      * Creates a new empty observable list backed by an arraylist.
 307      *
 308      * This list reports element updates.

 309      * @param extractor element to Observable[] convertor. Observable objects are listened for changes on the element.
 310      * @see #observableList(java.util.List, javafx.util.Callback)
 311      * @since JavaFX 2.1
 312      * @return a newly created ObservableList
 313      */
 314     public static <E> ObservableList<E> observableArrayList(Callback<E, Observable[]> extractor) {
 315         return observableList(new ArrayList(), extractor);
 316     }
 317 
 318     /**
 319      * Creates a new observable array list with {@code items} added to it.
 320      * @return a newly created observableArrayList
 321      * @param items the items that will be in the new observable ArrayList

 322      * @see #observableArrayList()
 323      */
 324     public static <E> ObservableList<E> observableArrayList(E... items) {
 325         ObservableList<E> list = observableArrayList();
 326         list.addAll(items);
 327         return list;
 328     }
 329 
 330     /**
 331      * Creates a new observable array list and adds a content of collection {@code col}
 332      * to it.

 333      * @param col a collection which content should be added to the observableArrayList
 334      * @return a newly created observableArrayList
 335      */
 336     public static <E> ObservableList<E> observableArrayList(Collection<? extends E> col) {
 337         ObservableList<E> list = observableArrayList();
 338         list.addAll(col);
 339         return list;
 340     }
 341 
 342     /**
 343      * Creates a new empty observable map that is backed by a HashMap.
 344      * @param <K> the type of keys
 345      * @param <V> the type of values
 346      * @return a newly created observable HashMap
 347      */
 348     public static <K,V> ObservableMap<K,V> observableHashMap() {
 349         return observableMap(new HashMap<K, V>());
 350     }
 351 
 352     /**
 353      * Concatenates more observable lists into one. The resulting list
 354      * would be backed by an arraylist.

 355      * @param lists lists to concatenate
 356      * @return new observable array list concatenated from the arguments
 357      */
 358     public static <E> ObservableList<E> concat(ObservableList<E>... lists) {
 359         if (lists.length == 0 ) {
 360             return observableArrayList();
 361         }
 362         if (lists.length == 1) {
 363             return observableArrayList(lists[0]);
 364         }
 365         ArrayList<E> backingList = new ArrayList<E>();
 366         for (ObservableList<E> s : lists) {
 367             backingList.addAll(s);
 368         }
 369 
 370         return observableList(backingList);
 371     }
 372 
 373     /**
 374      * Creates and returns unmodifiable wrapper list on top of provided observable list.
 375      * @param list  an ObservableList that is to be wrapped

 376      * @return an ObserableList wrapper that is unmodifiable
 377      * @see Collections#unmodifiableList(java.util.List)
 378      */
 379     public static<E> ObservableList<E> unmodifiableObservableList(ObservableList<E> list) {
 380         if (list == null) {
 381             throw new NullPointerException();
 382         }
 383         return new UnmodifiableObservableListImpl<E>(list);
 384     }
 385 
 386     /**
 387      * Creates and returns a typesafe wrapper on top of provided observable list.

 388      * @param list  an Observable list to be wrapped
 389      * @param type   the type of element that <tt>list</tt> is permitted to hold
 390      * @return a dynamically typesafe view of the specified list
 391      * @see Collections#checkedList(java.util.List, java.lang.Class)
 392      */
 393     public static<E> ObservableList<E> checkedObservableList(ObservableList<E> list, Class<E> type) {
 394         if (list == null) {
 395             throw new NullPointerException();
 396         }
 397         return new CheckedObservableList<E>(list, type);
 398     }
 399 
 400     /**
 401      * Creates and returns a synchronized wrapper on top of provided observable list.

 402      * @param  list the list to be "wrapped" in a synchronized list.
 403      * @return A synchronized version of the observable list
 404      * @see Collections#synchronizedList(java.util.List)
 405      */
 406     public static<E> ObservableList<E> synchronizedObservableList(ObservableList<E> list) {
 407         if (list == null) {
 408             throw new NullPointerException();
 409         }
 410         return new SynchronizedObservableList<E>(list);
 411     }
 412 
 413     private static ObservableList EMPTY_OBSERVABLE_LIST = new EmptyObservableList();
 414 
 415 
 416     /**
 417      * Creates and empty unmodifiable observable list.

 418      * @return An empty unmodifiable observable list
 419      * @see Collections#emptyList()
 420      */
 421     @SuppressWarnings("unchecked")
 422     public static<E> ObservableList<E> emptyObservableList() {
 423         return EMPTY_OBSERVABLE_LIST;
 424     }
 425 
 426     /**
 427      * Creates an unmodifiable observable list with single element.

 428      * @param e the only elements that will be contained in this singleton observable list
 429      * @return a singleton observable list
 430      * @see Collections#singletonList(java.lang.Object)
 431      */
 432     public static<E> ObservableList<E> singletonObservableList(E e) {
 433         return new SingletonObservableList<E>(e);
 434     }
 435 
 436     /**
 437      * Creates and returns unmodifiable wrapper on top of provided observable set.

 438      * @param set an ObservableSet that is to be wrapped
 439      * @return an ObserableSet wrapper that is unmodifiable
 440      * @see Collections#unmodifiableSet(java.util.Set)
 441      * @since JavaFX 8.0
 442      */
 443     public static<E> ObservableSet<E> unmodifiableObservableSet(ObservableSet<E> set) {
 444         if (set == null) {
 445             throw new NullPointerException();
 446         }
 447         return new UnmodifiableObservableSet<E>(set);
 448     }
 449 
 450     /**
 451      * Creates and returns a typesafe wrapper on top of provided observable set.

 452      * @param set an Observable set to be wrapped
 453      * @param type  the type of element that <tt>set</tt> is permitted to hold
 454      * @return a dynamically typesafe view of the specified set
 455      * @see Collections#checkedSet(java.util.Set, java.lang.Class)
 456      * @since JavaFX 8.0
 457      */
 458     public static<E> ObservableSet<E> checkedObservableSet(ObservableSet<E> set, Class<E> type) {
 459         if (set == null) {
 460             throw new NullPointerException();
 461         }
 462         return new CheckedObservableSet<E>(set, type);
 463     }
 464 
 465     /**
 466      * Creates and returns a synchronized wrapper on top of provided observable set.

 467      * @param  set the set to be "wrapped" in a synchronized set.
 468      * @return A synchronized version of the observable set
 469      * @see Collections#synchronizedSet(java.util.Set)
 470      * @since JavaFX 8.0
 471      */
 472     public static<E> ObservableSet<E> synchronizedObservableSet(ObservableSet<E> set) {
 473         if (set == null) {
 474             throw new NullPointerException();
 475         }
 476         return new SynchronizedObservableSet<E>(set);
 477     }
 478 
 479     private static ObservableSet EMPTY_OBSERVABLE_SET = new EmptyObservableSet();
 480 
 481     /**
 482      * Creates and empty unmodifiable observable set.

 483      * @return An empty unmodifiable observable set
 484      * @see Collections#emptySet()
 485      * @since JavaFX 8.0
 486      */
 487     @SuppressWarnings("unchecked")
 488     public static<E> ObservableSet<E> emptyObservableSet() {
 489         return EMPTY_OBSERVABLE_SET;
 490     }
 491 
 492     /**
 493      * Copies elements from src to dest. Fires only <b>one</b> change notification on dest.

 494      * @param dest the destination observable list
 495      * @param src the source list
 496      * @see Collections#copy(java.util.List, java.util.List)
 497      */
 498     @SuppressWarnings("unchecked")
 499     public static <T> void copy(ObservableList<? super T> dest, List<? extends T> src) {
 500         final int srcSize = src.size();
 501         if (srcSize > dest.size()) {
 502             throw new IndexOutOfBoundsException("Source does not fit in dest");
 503         }
 504         T[] destArray = (T[]) dest.toArray();
 505         System.arraycopy(src.toArray(), 0, destArray, 0, srcSize);
 506         dest.setAll(destArray);
 507     }
 508 
 509     /**
 510      * Fills the provided list with obj. Fires only <b>one</b> change notification on the list.

 511      * @param list the list to fill
 512      * @param obj the object to fill the list with
 513      * @see Collections#fill(java.util.List, java.lang.Object)
 514      */
 515     @SuppressWarnings("unchecked")
 516     public static <T> void fill(ObservableList<? super T> list, T obj) {
 517         T[] newContent = (T[]) new Object[list.size()];
 518         Arrays.fill(newContent, obj);
 519         list.setAll(newContent);
 520     }
 521 
 522     /**
 523      * Replace all oldVal elements in the list with newVal element.
 524      * Fires only <b>one</b> change notification on the list.

 525      * @param list the list which will have it's elements replaced
 526      * @param oldVal the element that is going to be replace
 527      * @param newVal the replacement
 528      * @return true if the list was modified
 529      * @see Collections#replaceAll(java.util.List, java.lang.Object, java.lang.Object)
 530      */
 531     @SuppressWarnings("unchecked")
 532     public static <T> boolean replaceAll(ObservableList<T> list, T oldVal, T newVal) {
 533         T[] newContent = (T[]) list.toArray();
 534         boolean modified = false;
 535         for (int i = 0 ; i < newContent.length; ++i) {
 536             if (newContent[i].equals(oldVal)) {
 537                 newContent[i] = newVal;
 538                 modified = true;
 539             }
 540         }
 541         if (modified) {
 542             list.setAll(newContent);
 543         }
 544         return modified;


 620     @SuppressWarnings("unchecked")
 621     public static void shuffle(ObservableList list, Random rnd) {
 622         Object newContent[] = list.toArray();
 623 
 624         for (int i = list.size(); i > 1; i--) {
 625             swap(newContent, i - 1, rnd.nextInt(i));
 626         }
 627 
 628         list.setAll(newContent);
 629     }
 630 
 631     private static void swap(Object[] arr, int i, int j) {
 632         Object tmp = arr[i];
 633         arr[i] = arr[j];
 634         arr[j] = tmp;
 635     }
 636 
 637     /**
 638      * Sorts the provided observable list.
 639      * Fires only <b>one</b> change notification on the list.


 640      * @see Collections#sort(java.util.List)
 641      */
 642     @SuppressWarnings("unchecked")
 643     public static <T extends Comparable<? super T>> void sort(ObservableList<T> list) {
 644         if (list instanceof SortableList) {
 645             ((SortableList<? extends T>)list).sort();
 646         } else {
 647             List<T> newContent = new ArrayList<T>(list);
 648             Collections.sort(newContent);
 649             list.setAll((Collection<T>)newContent);
 650         }
 651     }
 652 
 653     /**
 654      * Sorts the provided observable list using the c comparator.
 655      * Fires only <b>one</b> change notification on the list.

 656      * @param list the list to sort
 657      * @param c comparator used for sorting. Null if natural ordering is required.
 658      * @see Collections#sort(java.util.List, java.util.Comparator)
 659      */
 660     @SuppressWarnings("unchecked")
 661     public static <T> void sort(ObservableList<T> list, Comparator<? super T> c) {
 662         if (list instanceof SortableList) {
 663             ((SortableList<? extends T>)list).sort(c);
 664         } else {
 665             List<T> newContent = new ArrayList<T>(list);
 666             Collections.sort(newContent, c);
 667             list.setAll((Collection<T>)newContent);
 668         }
 669     }
 670 
 671     private static class EmptyObservableList<E> extends AbstractList<E> implements ObservableList<E> {
 672 
 673         private static final ListIterator iterator = new ListIterator() {
 674 
 675             @Override




  72  * therefore suitable for methods that require ObservableList on input.
  73  * <br><br>
  74  * The utility methods are here mainly for performance reasons. All methods are optimized in a way that
  75  * they yield only limited number of notifications. On the other hand, java.util.Collections methods
  76  * might call "modification methods" on an ObservableList multiple times, resulting in a number of notifications.
  77  *
  78  * @since JavaFX 2.0
  79  */
  80 public class FXCollections {
  81     /** Not to be instantiated. */
  82     private FXCollections() { }
  83 
  84     /**
  85      * Constructs an ObservableList that is backed by the specified list.
  86      * Mutation operations on the ObservableList instance will be reported
  87      * to observers that have registered on that instance.<br>
  88      * Note that mutation operations made directly to the underlying list are
  89      * <em>not</em> reported to observers of any ObservableList that
  90      * wraps it.
  91      *
  92      * @param <E> The type of List to be wrapped
  93      * @param list a concrete List that backs this ObservableList
  94      * @return a newly created ObservableList
  95      */
  96     public static <E> ObservableList<E> observableList(List<E> list) {
  97         if (list == null) {
  98             throw new NullPointerException();
  99         }
 100         return list instanceof RandomAccess ? new ObservableListWrapper<E>(list) :
 101                 new ObservableSequentialListWrapper<E>(list);
 102     }
 103 
 104     /**
 105      * Constructs an ObservableList that is backed by the specified list.
 106      * Mutation operations on the ObservableList instance will be reported
 107      * to observers that have registered on that instance.<br>
 108      * Note that mutation operations made directly to the underlying list are
 109      * <em>not</em> reported to observers of any ObservableList that
 110      * wraps it.
 111      * <br>
 112      * This list also reports mutations of the elements in it by using <code>extractor</code>.
 113      * Observable objects returned by extractor (applied to each list element) are listened for changes
 114      * and transformed into "update" change of ListChangeListener.
 115      *
 116      * @param <E> The type of List to be wrapped
 117      * @param list a concrete List that backs this ObservableList
 118      * @param extractor element to Observable[] convertor
 119      * @since JavaFX 2.1
 120      * @return a newly created ObservableList
 121      */
 122     public static <E> ObservableList<E> observableList(List<E> list, Callback<E, Observable[]> extractor) {
 123         if (list == null || extractor == null) {
 124             throw new NullPointerException();
 125         }
 126         return list instanceof RandomAccess ? new ObservableListWrapper<E>(list, extractor) :
 127             new ObservableSequentialListWrapper<E>(list, extractor);
 128     }
 129 
 130     /**
 131      * Constructs an ObservableMap that is backed by the specified map.
 132      * Mutation operations on the ObservableMap instance will be reported
 133      * to observers that have registered on that instance.<br>
 134      * Note that mutation operations made directly to the underlying map are <em>not</em>
 135      * reported to observers of any ObservableMap that wraps it.
 136      * @param <K> the type of the wrapped key
 137      * @param <V> the type of the wrapped value
 138      * @param map a Map that backs this ObservableMap
 139      * @return a newly created ObservableMap
 140      */
 141     public static <K, V> ObservableMap<K, V> observableMap(Map<K, V> map) {
 142         if (map == null) {
 143             throw new NullPointerException();
 144         }
 145         return new ObservableMapWrapper<K, V>(map);
 146     }
 147 
 148     /**
 149      * Constructs an ObservableSet that is backed by the specified set.
 150      * Mutation operations on the ObservableSet instance will be reported
 151      * to observers that have registered on that instance.<br>
 152      * Note that mutation operations made directly to the underlying set are <em>not</em>
 153      * reported to observers of any ObservableSet that wraps it.
 154      * @param <E> The type of List to be wrapped
 155      * @param set a Set that backs this ObservableSet
 156      * @return a newly created ObservableSet
 157      * @since JavaFX 2.1
 158      */
 159     public static <E> ObservableSet<E> observableSet(Set<E> set) {
 160         if (set == null) {
 161             throw new NullPointerException();
 162         }
 163         return new ObservableSetWrapper<E>(set);
 164     }
 165 
 166     /**
 167      * Constructs an ObservableSet backed by a HashSet
 168      * that contains all the specified elements.
 169      * @param <E> The type of List to be wrapped
 170      * @param elements elements that will be added into returned ObservableSet
 171      * @return a newly created ObservableSet
 172      * @since JavaFX 2.1
 173      */
 174     public static <E> ObservableSet<E> observableSet(E... elements) {
 175         if (elements == null) {
 176             throw new NullPointerException();
 177         }
 178         Set<E> set = new HashSet<E>(elements.length);
 179         Collections.addAll(set, elements);
 180         return new ObservableSetWrapper<E>(set);
 181     }
 182 
 183     /**
 184      * Constructs a read-only interface to the specified ObservableMap. Only
 185      * mutation operations made to the underlying ObservableMap will be reported
 186      * to observers that have registered on the unmodifiable instance. This allows
 187      * clients to track changes in a Map but disallows the ability to modify it.
 188      * @param <K> the type of the wrapped key
 189      * @param <V> the type of the wrapped value
 190      * @param map an ObservableMap that is to be monitored by this interface
 191      * @return a newly created UnmodifiableObservableMap
 192      */
 193     public static <K, V> ObservableMap<K, V> unmodifiableObservableMap(ObservableMap<K, V> map) {
 194         if (map == null) {
 195             throw new NullPointerException();
 196         }
 197         return new com.sun.javafx.collections.UnmodifiableObservableMap<K, V>(map);
 198     }
 199 
 200     /**
 201      * Creates and returns a typesafe wrapper on top of provided observable map.
 202      * @param <K> the type of the wrapped key
 203      * @param <V> the type of the wrapped value
 204      * @param map an Observable map to be wrapped
 205      * @param keyType the type of key that {@code map} is permitted to hold
 206      * @param valueType the type of value that {@code map} is permitted to hold
 207      * @return a dynamically typesafe view of the specified map
 208      * @see Collections#checkedMap(java.util.Map, java.lang.Class, java.lang.Class)
 209      * @since JavaFX 8.0
 210      */
 211     public static <K, V> ObservableMap<K, V> checkedObservableMap(ObservableMap<K, V> map, Class<K> keyType, Class<V> valueType) {
 212         if (map == null || keyType == null || valueType == null) {
 213             throw new NullPointerException();
 214         }
 215         return new CheckedObservableMap<K, V>(map, keyType, valueType);
 216     }
 217 
 218     /**
 219      * Creates and returns a synchronized wrapper on top of provided observable map.
 220      * @param <K> the type of the wrapped key
 221      * @param <V> the type of the wrapped value
 222      * @param  map the map to be "wrapped" in a synchronized map.
 223      * @return A synchronized version of the observable map
 224      * @see Collections#synchronizedMap(java.util.Map)
 225      * @since JavaFX 8.0
 226      */
 227     public static <K, V> ObservableMap<K, V> synchronizedObservableMap(ObservableMap<K, V> map) {
 228         if (map == null) {
 229             throw new NullPointerException();
 230         }
 231         return new SynchronizedObservableMap<K, V>(map);
 232     }
 233 
 234     private static ObservableMap EMPTY_OBSERVABLE_MAP = new EmptyObservableMap();
 235 
 236     /**
 237      * Creates and empty unmodifiable observable map.
 238      * @param <K> the type of the wrapped key
 239      * @param <V> the type of the wrapped value
 240      * @return An empty unmodifiable observable map
 241      * @see Collections#emptyMap()
 242      * @since JavaFX 8.0
 243      */
 244     @SuppressWarnings("unchecked")
 245     public static <K, V> ObservableMap<K, V> emptyObservableMap() {
 246         return EMPTY_OBSERVABLE_MAP;
 247     }
 248 
 249     /**
 250      * Creates a new empty observable integer array.
 251      * @return a newly created ObservableIntegerArray
 252      * @since JavaFX 8.0
 253      */
 254     public static ObservableIntegerArray observableIntegerArray() {
 255         return new ObservableIntegerArrayImpl();
 256     }
 257 
 258     /**
 259      * Creates a new observable integer array with {@code values} set to it.


 292      * @since JavaFX 8.0
 293      */
 294     public static ObservableFloatArray observableFloatArray(float... values) {
 295         return new ObservableFloatArrayImpl(values);
 296     }
 297 
 298     /**
 299      * Creates a new observable float array with copy of elements in given
 300      * {@code array}.
 301      * @param array observable float array to copy
 302      * @return a newly created ObservableFloatArray
 303      * @since JavaFX 8.0
 304      */
 305     public static ObservableFloatArray observableFloatArray(ObservableFloatArray array) {
 306         return new ObservableFloatArrayImpl(array);
 307     }
 308 
 309     /**
 310      * Creates a new empty observable list that is backed by an arraylist.
 311      * @see #observableList(java.util.List)
 312      * @param <E> The type of List to be wrapped
 313      * @return a newly created ObservableList
 314      */
 315     @SuppressWarnings("unchecked")
 316     public static <E> ObservableList<E> observableArrayList() {
 317         return observableList(new ArrayList());
 318     }
 319 
 320     /**
 321      * Creates a new empty observable list backed by an arraylist.
 322      *
 323      * This list reports element updates.
 324      * @param <E> The type of List to be wrapped
 325      * @param extractor element to Observable[] convertor. Observable objects are listened for changes on the element.
 326      * @see #observableList(java.util.List, javafx.util.Callback)
 327      * @since JavaFX 2.1
 328      * @return a newly created ObservableList
 329      */
 330     public static <E> ObservableList<E> observableArrayList(Callback<E, Observable[]> extractor) {
 331         return observableList(new ArrayList(), extractor);
 332     }
 333 
 334     /**
 335      * Creates a new observable array list with {@code items} added to it.
 336      * @param <E> The type of List to be wrapped
 337      * @param items the items that will be in the new observable ArrayList
 338      * @return a newly created observableArrayList
 339      * @see #observableArrayList()
 340      */
 341     public static <E> ObservableList<E> observableArrayList(E... items) {
 342         ObservableList<E> list = observableArrayList();
 343         list.addAll(items);
 344         return list;
 345     }
 346 
 347     /**
 348      * Creates a new observable array list and adds a content of collection {@code col}
 349      * to it.
 350      * @param <E> The type of List to be wrapped
 351      * @param col a collection which content should be added to the observableArrayList
 352      * @return a newly created observableArrayList
 353      */
 354     public static <E> ObservableList<E> observableArrayList(Collection<? extends E> col) {
 355         ObservableList<E> list = observableArrayList();
 356         list.addAll(col);
 357         return list;
 358     }
 359 
 360     /**
 361      * Creates a new empty observable map that is backed by a HashMap.
 362      * @param <K> the type of the wrapped key
 363      * @param <V> the type of the wrapped value
 364      * @return a newly created observable HashMap
 365      */
 366     public static <K,V> ObservableMap<K,V> observableHashMap() {
 367         return observableMap(new HashMap<K, V>());
 368     }
 369 
 370     /**
 371      * Concatenates more observable lists into one. The resulting list
 372      * would be backed by an arraylist.
 373      * @param <E> The type of List to be wrapped
 374      * @param lists lists to concatenate
 375      * @return new observable array list concatenated from the arguments
 376      */
 377     public static <E> ObservableList<E> concat(ObservableList<E>... lists) {
 378         if (lists.length == 0 ) {
 379             return observableArrayList();
 380         }
 381         if (lists.length == 1) {
 382             return observableArrayList(lists[0]);
 383         }
 384         ArrayList<E> backingList = new ArrayList<E>();
 385         for (ObservableList<E> s : lists) {
 386             backingList.addAll(s);
 387         }
 388 
 389         return observableList(backingList);
 390     }
 391 
 392     /**
 393      * Creates and returns unmodifiable wrapper list on top of provided observable list.
 394      * @param list  an ObservableList that is to be wrapped
 395      * @param <E> The type of List to be wrapped
 396      * @return an ObserableList wrapper that is unmodifiable
 397      * @see Collections#unmodifiableList(java.util.List)
 398      */
 399     public static<E> ObservableList<E> unmodifiableObservableList(ObservableList<E> list) {
 400         if (list == null) {
 401             throw new NullPointerException();
 402         }
 403         return new UnmodifiableObservableListImpl<E>(list);
 404     }
 405 
 406     /**
 407      * Creates and returns a typesafe wrapper on top of provided observable list.
 408      * @param <E> The type of List to be wrapped
 409      * @param list  an Observable list to be wrapped
 410      * @param type   the type of element that <tt>list</tt> is permitted to hold
 411      * @return a dynamically typesafe view of the specified list
 412      * @see Collections#checkedList(java.util.List, java.lang.Class)
 413      */
 414     public static<E> ObservableList<E> checkedObservableList(ObservableList<E> list, Class<E> type) {
 415         if (list == null) {
 416             throw new NullPointerException();
 417         }
 418         return new CheckedObservableList<E>(list, type);
 419     }
 420 
 421     /**
 422      * Creates and returns a synchronized wrapper on top of provided observable list.
 423      * @param <E> The type of List to be wrapped
 424      * @param  list the list to be "wrapped" in a synchronized list.
 425      * @return A synchronized version of the observable list
 426      * @see Collections#synchronizedList(java.util.List)
 427      */
 428     public static<E> ObservableList<E> synchronizedObservableList(ObservableList<E> list) {
 429         if (list == null) {
 430             throw new NullPointerException();
 431         }
 432         return new SynchronizedObservableList<E>(list);
 433     }
 434 
 435     private static ObservableList EMPTY_OBSERVABLE_LIST = new EmptyObservableList();
 436 
 437 
 438     /**
 439      * Creates and empty unmodifiable observable list.
 440      * @param <E> The type of List to be wrapped
 441      * @return An empty unmodifiable observable list
 442      * @see Collections#emptyList()
 443      */
 444     @SuppressWarnings("unchecked")
 445     public static<E> ObservableList<E> emptyObservableList() {
 446         return EMPTY_OBSERVABLE_LIST;
 447     }
 448 
 449     /**
 450      * Creates an unmodifiable observable list with single element.
 451      * @param <E> The type of List to be wrapped
 452      * @param e the only elements that will be contained in this singleton observable list
 453      * @return a singleton observable list
 454      * @see Collections#singletonList(java.lang.Object)
 455      */
 456     public static<E> ObservableList<E> singletonObservableList(E e) {
 457         return new SingletonObservableList<E>(e);
 458     }
 459 
 460     /**
 461      * Creates and returns unmodifiable wrapper on top of provided observable set.
 462      * @param <E> The type of List to be wrapped
 463      * @param set an ObservableSet that is to be wrapped
 464      * @return an ObserableSet wrapper that is unmodifiable
 465      * @see Collections#unmodifiableSet(java.util.Set)
 466      * @since JavaFX 8.0
 467      */
 468     public static<E> ObservableSet<E> unmodifiableObservableSet(ObservableSet<E> set) {
 469         if (set == null) {
 470             throw new NullPointerException();
 471         }
 472         return new UnmodifiableObservableSet<E>(set);
 473     }
 474 
 475     /**
 476      * Creates and returns a typesafe wrapper on top of provided observable set.
 477      * @param <E> The type of List to be wrapped
 478      * @param set an Observable set to be wrapped
 479      * @param type  the type of element that <tt>set</tt> is permitted to hold
 480      * @return a dynamically typesafe view of the specified set
 481      * @see Collections#checkedSet(java.util.Set, java.lang.Class)
 482      * @since JavaFX 8.0
 483      */
 484     public static<E> ObservableSet<E> checkedObservableSet(ObservableSet<E> set, Class<E> type) {
 485         if (set == null) {
 486             throw new NullPointerException();
 487         }
 488         return new CheckedObservableSet<E>(set, type);
 489     }
 490 
 491     /**
 492      * Creates and returns a synchronized wrapper on top of provided observable set.
 493      * @param <E> The type of List to be wrapped
 494      * @param  set the set to be "wrapped" in a synchronized set.
 495      * @return A synchronized version of the observable set
 496      * @see Collections#synchronizedSet(java.util.Set)
 497      * @since JavaFX 8.0
 498      */
 499     public static<E> ObservableSet<E> synchronizedObservableSet(ObservableSet<E> set) {
 500         if (set == null) {
 501             throw new NullPointerException();
 502         }
 503         return new SynchronizedObservableSet<E>(set);
 504     }
 505 
 506     private static ObservableSet EMPTY_OBSERVABLE_SET = new EmptyObservableSet();
 507 
 508     /**
 509      * Creates and empty unmodifiable observable set.
 510      * @param <E> The type of List to be wrapped
 511      * @return An empty unmodifiable observable set
 512      * @see Collections#emptySet()
 513      * @since JavaFX 8.0
 514      */
 515     @SuppressWarnings("unchecked")
 516     public static<E> ObservableSet<E> emptyObservableSet() {
 517         return EMPTY_OBSERVABLE_SET;
 518     }
 519 
 520     /**
 521      * Copies elements from src to dest. Fires only <b>one</b> change notification on dest.
 522      * @param <T> The type of List to be wrapped
 523      * @param dest the destination observable list
 524      * @param src the source list
 525      * @see Collections#copy(java.util.List, java.util.List)
 526      */
 527     @SuppressWarnings("unchecked")
 528     public static <T> void copy(ObservableList<? super T> dest, List<? extends T> src) {
 529         final int srcSize = src.size();
 530         if (srcSize > dest.size()) {
 531             throw new IndexOutOfBoundsException("Source does not fit in dest");
 532         }
 533         T[] destArray = (T[]) dest.toArray();
 534         System.arraycopy(src.toArray(), 0, destArray, 0, srcSize);
 535         dest.setAll(destArray);
 536     }
 537 
 538     /**
 539      * Fills the provided list with obj. Fires only <b>one</b> change notification on the list.
 540      * @param <T> The type of List to be wrapped
 541      * @param list the list to fill
 542      * @param obj the object to fill the list with
 543      * @see Collections#fill(java.util.List, java.lang.Object)
 544      */
 545     @SuppressWarnings("unchecked")
 546     public static <T> void fill(ObservableList<? super T> list, T obj) {
 547         T[] newContent = (T[]) new Object[list.size()];
 548         Arrays.fill(newContent, obj);
 549         list.setAll(newContent);
 550     }
 551 
 552     /**
 553      * Replace all oldVal elements in the list with newVal element.
 554      * Fires only <b>one</b> change notification on the list.
 555      * @param <T> The type of List to be wrapped
 556      * @param list the list which will have it's elements replaced
 557      * @param oldVal the element that is going to be replace
 558      * @param newVal the replacement
 559      * @return true if the list was modified
 560      * @see Collections#replaceAll(java.util.List, java.lang.Object, java.lang.Object)
 561      */
 562     @SuppressWarnings("unchecked")
 563     public static <T> boolean replaceAll(ObservableList<T> list, T oldVal, T newVal) {
 564         T[] newContent = (T[]) list.toArray();
 565         boolean modified = false;
 566         for (int i = 0 ; i < newContent.length; ++i) {
 567             if (newContent[i].equals(oldVal)) {
 568                 newContent[i] = newVal;
 569                 modified = true;
 570             }
 571         }
 572         if (modified) {
 573             list.setAll(newContent);
 574         }
 575         return modified;


 651     @SuppressWarnings("unchecked")
 652     public static void shuffle(ObservableList list, Random rnd) {
 653         Object newContent[] = list.toArray();
 654 
 655         for (int i = list.size(); i > 1; i--) {
 656             swap(newContent, i - 1, rnd.nextInt(i));
 657         }
 658 
 659         list.setAll(newContent);
 660     }
 661 
 662     private static void swap(Object[] arr, int i, int j) {
 663         Object tmp = arr[i];
 664         arr[i] = arr[j];
 665         arr[j] = tmp;
 666     }
 667 
 668     /**
 669      * Sorts the provided observable list.
 670      * Fires only <b>one</b> change notification on the list.
 671      * @param <T> The type of List to be wrapped
 672      * @param list the list to be sorted
 673      * @see Collections#sort(java.util.List)
 674      */
 675     @SuppressWarnings("unchecked")
 676     public static <T extends Comparable<? super T>> void sort(ObservableList<T> list) {
 677         if (list instanceof SortableList) {
 678             ((SortableList<? extends T>)list).sort();
 679         } else {
 680             List<T> newContent = new ArrayList<T>(list);
 681             Collections.sort(newContent);
 682             list.setAll((Collection<T>)newContent);
 683         }
 684     }
 685 
 686     /**
 687      * Sorts the provided observable list using the c comparator.
 688      * Fires only <b>one</b> change notification on the list.
 689      * @param <T> The type of List to be wrapped
 690      * @param list the list to sort
 691      * @param c comparator used for sorting. Null if natural ordering is required.
 692      * @see Collections#sort(java.util.List, java.util.Comparator)
 693      */
 694     @SuppressWarnings("unchecked")
 695     public static <T> void sort(ObservableList<T> list, Comparator<? super T> c) {
 696         if (list instanceof SortableList) {
 697             ((SortableList<? extends T>)list).sort(c);
 698         } else {
 699             List<T> newContent = new ArrayList<T>(list);
 700             Collections.sort(newContent, c);
 701             list.setAll((Collection<T>)newContent);
 702         }
 703     }
 704 
 705     private static class EmptyObservableList<E> extends AbstractList<E> implements ObservableList<E> {
 706 
 707         private static final ListIterator iterator = new ListIterator() {
 708 
 709             @Override


< prev index next >