001 /*
002 * Copyright 2008-2017 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package griffon.javafx.beans.binding;
017
018 import javafx.beans.InvalidationListener;
019 import javafx.beans.Observable;
020 import javafx.beans.property.BooleanProperty;
021 import javafx.beans.property.DoubleProperty;
022 import javafx.beans.property.FloatProperty;
023 import javafx.beans.property.IntegerProperty;
024 import javafx.beans.property.ListProperty;
025 import javafx.beans.property.LongProperty;
026 import javafx.beans.property.MapProperty;
027 import javafx.beans.property.ObjectProperty;
028 import javafx.beans.property.Property;
029 import javafx.beans.property.SetProperty;
030 import javafx.beans.property.StringProperty;
031 import javafx.beans.value.ChangeListener;
032 import javafx.beans.value.ObservableBooleanValue;
033 import javafx.beans.value.ObservableDoubleValue;
034 import javafx.beans.value.ObservableFloatValue;
035 import javafx.beans.value.ObservableIntegerValue;
036 import javafx.beans.value.ObservableLongValue;
037 import javafx.beans.value.ObservableStringValue;
038 import javafx.beans.value.ObservableValue;
039 import javafx.collections.ListChangeListener;
040 import javafx.collections.MapChangeListener;
041 import javafx.collections.ObservableList;
042 import javafx.collections.ObservableMap;
043 import javafx.collections.ObservableSet;
044 import javafx.collections.SetChangeListener;
045
046 import javax.annotation.Nonnull;
047 import java.util.function.Consumer;
048
049 import static java.util.Objects.requireNonNull;
050
051 /**
052 * @author Andres Almiray
053 * @since 2.9.0
054 */
055 public final class UIThreadAwareBindings {
056 private static final String ERROR_LISTENER_NULL = "Argument 'listener' must not be null";
057 private static final String ERROR_CONSUMER_NULL = "Argument 'consumer' must not be null";
058 private static final String ERROR_RUNNABLE_NULL = "Argument 'runnable' must not be null";
059 private static final String ERROR_OBSERVABLE_NULL = "Argument 'observable' must not be null";
060 private static final String ERROR_PROPERTY_NULL = "Argument 'property' must not be null";
061
062 private UIThreadAwareBindings() {
063 // prevent instantiation
064 }
065
066 /**
067 * Registers a {@code ChangeListener} on the supplied observable that will notify the target property.
068 *
069 * @param property the property that will be notified of value changes.
070 * @param observable the observable on which the listener will be registered.
071 *
072 * @return the wrapped change listener.
073 *
074 * @since 2.11.0
075 */
076 public static <T> ChangeListener<T> uiThreadAwareBind(@Nonnull final Property<T> property, @Nonnull final ObservableValue<T> observable) {
077 requireNonNull(property, ERROR_PROPERTY_NULL);
078 property.setValue(observable.getValue());
079 return uiThreadAwareChangeListener(observable, (v, o, n) -> property.setValue(n));
080 }
081
082 /**
083 * Registers a {@code ChangeListener} that always handles notifications inside the UI thread.
084 *
085 * @param observable the observable on which the listener will be registered.
086 * @param listener the wrapped change listener.
087 *
088 * @return a {@code ChangeListener}.
089 */
090 public static <T> ChangeListener<T> uiThreadAwareChangeListener(@Nonnull final ObservableValue<T> observable, @Nonnull ChangeListener<T> listener) {
091 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
092 ChangeListener<T> uiListener = uiThreadAwareChangeListener(listener);
093 observable.addListener(uiListener);
094 return uiListener;
095 }
096
097 /**
098 * Creates a {@code ChangeListener} that always handles notifications inside the UI thread.
099 *
100 * @param listener the wrapped change listener.
101 *
102 * @return a {@code ChangeListener}.
103 */
104 @Nonnull
105 public static <T> ChangeListener<T> uiThreadAwareChangeListener(@Nonnull ChangeListener<T> listener) {
106 requireNonNull(listener, ERROR_LISTENER_NULL);
107 return listener instanceof UIThreadAware ? listener : new UIThreadAwareChangeListener<>(listener);
108 }
109
110 /**
111 * Registers a {@code ChangeListener} that always handles notifications inside the UI thread.
112 *
113 * @param observable the observable on which the listener will be registered.
114 * @param consumer the consumer of the {@code newValue} argument.
115 *
116 * @return a {@code ChangeListener}.
117 */
118 public static <T> ChangeListener<T> uiThreadAwareChangeListener(@Nonnull final ObservableValue<T> observable, @Nonnull final Consumer<T> consumer) {
119 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
120 ChangeListener<T> listener = uiThreadAwareChangeListener(consumer);
121 observable.addListener(listener);
122 return listener;
123 }
124
125 /**
126 * Creates a {@code ChangeListener} that always handles notifications inside the UI thread.
127 *
128 * @param consumer the consumer of the {@code newValue} argument.
129 *
130 * @return a {@code ChangeListener}.
131 */
132 @Nonnull
133 public static <T> ChangeListener<T> uiThreadAwareChangeListener(@Nonnull final Consumer<T> consumer) {
134 requireNonNull(consumer, ERROR_CONSUMER_NULL);
135 return new UIThreadAwareChangeListener<>((observable, oldValue, newValue) -> consumer.accept(newValue));
136 }
137
138 /**
139 * Registers a {@code ChangeListener} that always handles notifications inside the UI thread.
140 *
141 * @param observable the observable on which the listener will be registered.
142 * @param runnable the code to be executed when the listener is notified.
143 *
144 * @return a {@code ChangeListener}.
145 */
146 public static <T> ChangeListener<T> uiThreadAwareChangeListener(@Nonnull final ObservableValue<T> observable, @Nonnull final Runnable runnable) {
147 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
148 ChangeListener<T> listener = uiThreadAwareChangeListener(runnable);
149 observable.addListener(listener);
150 return listener;
151 }
152
153 /**
154 * Creates a {@code ChangeListener} that always handles notifications inside the UI thread.
155 *
156 * @param runnable the code to be executed when the listener is notified.
157 *
158 * @return a {@code ChangeListener}.
159 */
160 @Nonnull
161 public static <T> ChangeListener<T> uiThreadAwareChangeListener(@Nonnull final Runnable runnable) {
162 requireNonNull(runnable, ERROR_RUNNABLE_NULL);
163 return new UIThreadAwareChangeListener<>((observable, oldValue, newValue) -> runnable.run());
164 }
165
166 /**
167 * Registers a {@code InvalidationListener} that always handles notifications inside the UI thread.
168 *
169 * @param observable the observable on which the listener will be registered.
170 * @param listener the wrapped invalidation listener.
171 *
172 * @return an {@code InvalidationListener}.
173 */
174 public static InvalidationListener uiThreadAwareInvalidationListener(@Nonnull final Observable observable, @Nonnull InvalidationListener listener) {
175 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
176 InvalidationListener uiListener = uiThreadAwareInvalidationListener(listener);
177 observable.addListener(uiListener);
178 return uiListener;
179 }
180
181 /**
182 * Creates a {@code InvalidationListener} that always handles notifications inside the UI thread.
183 *
184 * @param listener the wrapped invalidation listener.
185 *
186 * @return a {@code InvalidationListener}.
187 */
188 @Nonnull
189 public static InvalidationListener uiThreadAwareInvalidationListener(@Nonnull InvalidationListener listener) {
190 requireNonNull(listener, ERROR_LISTENER_NULL);
191 return listener instanceof UIThreadAware ? listener : new UIThreadAwareInvalidationListener(listener);
192 }
193
194 /**
195 * Registers a {@code InvalidationListener} that always handles notifications inside the UI thread.
196 *
197 * @param observable the observable on which the listener will be registered.
198 * @param consumer the consumer of the {@code observable} argument.
199 *
200 * @return a {@code InvalidationListener}.
201 */
202 public static InvalidationListener uiThreadAwareInvalidationListener(@Nonnull final Observable observable, @Nonnull final Consumer<Observable> consumer) {
203 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
204 InvalidationListener listener = uiThreadAwareInvalidationListener(consumer);
205 observable.addListener(listener);
206 return listener;
207 }
208
209 /**
210 * Creates a {@code InvalidationListener} that always handles notifications inside the UI thread.
211 *
212 * @param consumer the consumer of the {@code observable} argument.
213 *
214 * @return a {@code InvalidationListener}.
215 */
216 @Nonnull
217 public static InvalidationListener uiThreadAwareInvalidationListener(@Nonnull final Consumer<Observable> consumer) {
218 requireNonNull(consumer, ERROR_CONSUMER_NULL);
219 return new UIThreadAwareInvalidationListener(consumer::accept);
220 }
221
222 /**
223 * Registers a {@code InvalidationListener} that always handles notifications inside the UI thread.
224 *
225 * @param observable the observable on which the listener will be registered.
226 * @param runnable the code to be executed when the listener is notified.
227 *
228 * @return a {@code InvalidationListener}.
229 */
230 public static InvalidationListener uiThreadAwareInvalidationListener(@Nonnull final Observable observable, @Nonnull final Runnable runnable) {
231 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
232 InvalidationListener listener = uiThreadAwareInvalidationListener(runnable);
233 observable.addListener(listener);
234 return listener;
235 }
236
237 /**
238 * Creates a {@code InvalidationListener} that always handles notifications inside the UI thread.
239 *
240 * @param runnable the code to be executed when the listener is notified.
241 *
242 * @return a {@code InvalidationListener}.
243 */
244 @Nonnull
245 public static InvalidationListener uiThreadAwareInvalidationListener(@Nonnull final Runnable runnable) {
246 requireNonNull(runnable, ERROR_RUNNABLE_NULL);
247 return new UIThreadAwareInvalidationListener(observable -> runnable.run());
248 }
249
250 /**
251 * Registers a {@code ListChangeListener} that always handles notifications inside the UI thread.
252 *
253 * @param observable the observable on which the listener will be registered.
254 * @param listener the wrapped list change listener.
255 *
256 * @return a {@code ListChangeListener}.
257 */
258 public static <E> ListChangeListener<E> uiThreadAwareListChangeListener(@Nonnull final ObservableList<E> observable, @Nonnull ListChangeListener<E> listener) {
259 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
260 ListChangeListener<E> uiListener = uiThreadAwareListChangeListener(listener);
261 observable.addListener(uiListener);
262 return listener;
263 }
264
265 /**
266 * Creates a {@code ListChangeListener} that always handles notifications inside the UI thread.
267 *
268 * @param listener the wrapped list change listener.
269 *
270 * @return a {@code ListChangeListener}.
271 */
272 @Nonnull
273 public static <E> ListChangeListener<E> uiThreadAwareListChangeListener(@Nonnull ListChangeListener<E> listener) {
274 requireNonNull(listener, ERROR_LISTENER_NULL);
275 return listener instanceof UIThreadAware ? listener : new UIThreadAwareListChangeListener<>(listener);
276 }
277
278 /**
279 * Registers a {@code ListChangeListener} that always handles notifications inside the UI thread.
280 *
281 * @param observable the observable on which the listener will be registered.
282 * @param consumer the consumer of the {@code newValue} argument.
283 *
284 * @return a {@code ListChangeListener}.
285 */
286 public static <E> ListChangeListener<E> uiThreadAwareListChangeListener(@Nonnull final ObservableList<E> observable, @Nonnull final Consumer<ListChangeListener.Change<? extends E>> consumer) {
287 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
288 ListChangeListener<E> listener = uiThreadAwareListChangeListener(consumer);
289 observable.addListener(listener);
290 return listener;
291 }
292
293 /**
294 * Creates a {@code ListChangeListener} that always handles notifications inside the UI thread.
295 *
296 * @param consumer the consumer of the {@code change} argument.
297 *
298 * @return a {@code ListChangeListener}.
299 */
300 @Nonnull
301 public static <E> ListChangeListener<E> uiThreadAwareListChangeListener(@Nonnull final Consumer<ListChangeListener.Change<? extends E>> consumer) {
302 requireNonNull(consumer, ERROR_CONSUMER_NULL);
303 return new UIThreadAwareListChangeListener<E>(consumer::accept);
304 }
305
306 /**
307 * Registers a {@code ListChangeListener} that always handles notifications inside the UI thread.
308 *
309 * @param observable the observable on which the listener will be registered.
310 * @param runnable the code to be executed when the listener is notified.
311 *
312 * @return a {@code ListChangeListener}.
313 */
314 public static <E> ListChangeListener<E> uiThreadAwareListChangeListener(@Nonnull final ObservableList<E> observable, @Nonnull final Runnable runnable) {
315 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
316 ListChangeListener<E> listener = uiThreadAwareListChangeListener(runnable);
317 observable.addListener(listener);
318 return listener;
319 }
320
321 /**
322 * Creates a {@code ListChangeListener} that always handles notifications inside the UI thread.
323 *
324 * @param runnable the code to be executed when the listener is notified.
325 *
326 * @return a {@code ListChangeListener}.
327 */
328 @Nonnull
329 public static <E> ListChangeListener<E> uiThreadAwareListChangeListener(@Nonnull final Runnable runnable) {
330 requireNonNull(runnable, ERROR_RUNNABLE_NULL);
331 return new UIThreadAwareListChangeListener<>(change -> runnable.run());
332 }
333
334 /**
335 * Registers a {@code MapChangeListener} that always handles notifications inside the UI thread.
336 *
337 * @param observable the observable on which the listener will be registered.
338 * @param listener the wrapped map change listener.
339 *
340 * @return a {@code MapChangeListener}.
341 */
342 public static <K, V> MapChangeListener<K, V> uiThreadAwareMapChangeListener(@Nonnull final ObservableMap<K, V> observable, @Nonnull MapChangeListener<K, V> listener) {
343 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
344 MapChangeListener<K, V> uiListener = uiThreadAwareMapChangeListener(listener);
345 observable.addListener(uiListener);
346 return listener;
347 }
348
349 /**
350 * Creates a {@code MapChangeListener} that always handles notifications inside the UI thread.
351 *
352 * @param listener the wrapped map change listener.
353 *
354 * @return a {@code MapChangeListener}.
355 */
356 @Nonnull
357 public static <K, V> MapChangeListener<K, V> uiThreadAwareMapChangeListener(@Nonnull MapChangeListener<K, V> listener) {
358 requireNonNull(listener, ERROR_LISTENER_NULL);
359 return listener instanceof UIThreadAware ? listener : new UIThreadAwareMapChangeListener<>(listener);
360 }
361
362 /**
363 * Registers a {@code MapChangeListener} that always handles notifications inside the UI thread.
364 *
365 * @param observable the observable on which the listener will be registered.
366 * @param consumer the consumer of the {@code newValue} argument.
367 *
368 * @return a {@code MapChangeListener}.
369 */
370 public static <K, V> MapChangeListener<K, V> uiThreadAwareMapChangeListener(@Nonnull final ObservableMap<K, V> observable, @Nonnull final Consumer<MapChangeListener.Change<? extends K, ? extends V>> consumer) {
371 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
372 MapChangeListener<K, V> listener = uiThreadAwareMapChangeListener(consumer);
373 observable.addListener(listener);
374 return listener;
375 }
376
377 /**
378 * Creates a {@code MapChangeListener} that always handles notifications inside the UI thread.
379 *
380 * @param consumer the consumer of the {@code change} argument.
381 *
382 * @return a {@code MapChangeListener}.
383 */
384 @Nonnull
385 public static <K, V> MapChangeListener<K, V> uiThreadAwareMapChangeListener(@Nonnull final Consumer<MapChangeListener.Change<? extends K, ? extends V>> consumer) {
386 requireNonNull(consumer, ERROR_CONSUMER_NULL);
387 return new UIThreadAwareMapChangeListener<K, V>(consumer::accept);
388 }
389
390 /**
391 * Registers a {@code MapChangeListener} that always handles notifications inside the UI thread.
392 *
393 * @param observable the observable on which the listener will be registered.
394 * @param runnable the code to be executed when the listener is notified.
395 *
396 * @return a {@code MapChangeListener}.
397 */
398 public static <K, V> MapChangeListener<K, V> uiThreadAwareMapChangeListener(@Nonnull final ObservableMap<K, V> observable, @Nonnull final Runnable runnable) {
399 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
400 MapChangeListener<K, V> listener = uiThreadAwareMapChangeListener(runnable);
401 observable.addListener(listener);
402 return listener;
403 }
404
405 /**
406 * Creates a {@code MapChangeListener} that always handles notifications inside the UI thread.
407 *
408 * @param runnable the code to be executed when the listener is notified.
409 *
410 * @return a {@code MapChangeListener}.
411 */
412 @Nonnull
413 public static <K, V> MapChangeListener<K, V> uiThreadAwareMapChangeListener(@Nonnull final Runnable runnable) {
414 requireNonNull(runnable, ERROR_RUNNABLE_NULL);
415 return new UIThreadAwareMapChangeListener<>(change -> runnable.run());
416 }
417
418 /**
419 * Registers a {@code SetChangeListener} that always handles notifications inside the UI thread.
420 *
421 * @param observable the observable on which the listener will be registered.
422 * @param listener the wrapped set change listener.
423 *
424 * @return a {@code SetChangeListener}.
425 */
426 public static <E> SetChangeListener<E> uiThreadAwareSetChangeListener(@Nonnull final ObservableSet<E> observable, @Nonnull SetChangeListener<E> listener) {
427 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
428 SetChangeListener<E> uiListener = uiThreadAwareSetChangeListener(listener);
429 observable.addListener(uiListener);
430 return listener;
431 }
432
433 /**
434 * Creates a {@code SetChangeListener} that always handles notifications inside the UI thread.
435 *
436 * @param listener the wrapped set change listener.
437 *
438 * @return a {@code SetChangeListener}.
439 */
440 @Nonnull
441 public static <E> SetChangeListener<E> uiThreadAwareSetChangeListener(@Nonnull SetChangeListener<E> listener) {
442 requireNonNull(listener, ERROR_LISTENER_NULL);
443 return listener instanceof UIThreadAware ? listener : new UIThreadAwareSetChangeListener<>(listener);
444 }
445
446 /**
447 * Registers a {@code SetChangeListener} that always handles notifications inside the UI thread.
448 *
449 * @param observable the observable on which the listener will be registered.
450 * @param consumer the consumer of the {@code newValue} argument.
451 *
452 * @return a {@code SetChangeListener}.
453 */
454 public static <E> SetChangeListener<E> uiThreadAwareSetChangeListener(@Nonnull final ObservableSet<E> observable, @Nonnull final Consumer<SetChangeListener.Change<? extends E>> consumer) {
455 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
456 SetChangeListener<E> listener = uiThreadAwareSetChangeListener(consumer);
457 observable.addListener(listener);
458 return listener;
459 }
460
461 /**
462 * Creates a {@code SetChangeListener} that always handles notifications inside the UI thread.
463 *
464 * @param consumer the consumer of the {@code change} argument.
465 *
466 * @return a {@code SetChangeListener}.
467 */
468 @Nonnull
469 public static <E> SetChangeListener<E> uiThreadAwareSetChangeListener(@Nonnull final Consumer<SetChangeListener.Change<? extends E>> consumer) {
470 requireNonNull(consumer, ERROR_CONSUMER_NULL);
471 return new UIThreadAwareSetChangeListener<E>(consumer::accept);
472 }
473
474 /**
475 * Registers a {@code SetChangeListener} that always handles notifications inside the UI thread.
476 *
477 * @param observable the observable on which the listener will be registered.
478 * @param runnable the code to be executed when the listener is notified.
479 *
480 * @return a {@code SetChangeListener}.
481 */
482 public static <E> SetChangeListener<E> uiThreadAwareSetChangeListener(@Nonnull final ObservableSet<E> observable, @Nonnull final Runnable runnable) {
483 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
484 SetChangeListener<E> listener = uiThreadAwareSetChangeListener(runnable);
485 observable.addListener(listener);
486 return listener;
487 }
488
489 /**
490 * Creates a {@code SetChangeListener} that always handles notifications inside the UI thread.
491 *
492 * @param runnable the code to be executed when the listener is notified.
493 *
494 * @return a {@code SetChangeListener}.
495 */
496 @Nonnull
497 public static <E> SetChangeListener<E> uiThreadAwareSetChangeListener(@Nonnull final Runnable runnable) {
498 requireNonNull(runnable, ERROR_RUNNABLE_NULL);
499 return new UIThreadAwareSetChangeListener<>(change -> runnable.run());
500 }
501
502 /**
503 * Creates an observable boolean property that notifies its listeners inside the UI thread.
504 *
505 * @param observable the observable boolean property to wrap.
506 *
507 * @return an observable boolean property.
508 */
509 @Nonnull
510 public static BooleanProperty uiThreadAwareBooleanProperty(@Nonnull BooleanProperty observable) {
511 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
512 return observable instanceof UIThreadAware ? observable : new UIThreadAwareBooleanProperty(observable);
513 }
514
515 /**
516 * Creates an observable integer property that notifies its listeners inside the UI thread.
517 *
518 * @param observable the observable integer property to wrap.
519 *
520 * @return an observable integer property.
521 */
522 @Nonnull
523 public static IntegerProperty uiThreadAwareIntegerProperty(@Nonnull IntegerProperty observable) {
524 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
525 return observable instanceof UIThreadAware ? observable : new UIThreadAwareIntegerProperty(observable);
526 }
527
528 /**
529 * Creates an observable long property that notifies its listeners inside the UI thread.
530 *
531 * @param observable the observable long property to wrap.
532 *
533 * @return an observable long property.
534 */
535 @Nonnull
536 public static LongProperty uiThreadAwareLongProperty(@Nonnull LongProperty observable) {
537 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
538 return observable instanceof UIThreadAware ? observable : new UIThreadAwareLongProperty(observable);
539 }
540
541 /**
542 * Creates an observable float property that notifies its listeners inside the UI thread.
543 *
544 * @param observable the observable float property to wrap.
545 *
546 * @return an observable float property.
547 */
548 @Nonnull
549 public static FloatProperty uiThreadAwareFloatProperty(@Nonnull FloatProperty observable) {
550 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
551 return observable instanceof UIThreadAware ? observable : new UIThreadAwareFloatProperty(observable);
552 }
553
554 /**
555 * Creates an observable double property that notifies its listeners inside the UI thread.
556 *
557 * @param observable the observable double property to wrap.
558 *
559 * @return an observable double property.
560 */
561 @Nonnull
562 public static DoubleProperty uiThreadAwareDoubleProperty(@Nonnull DoubleProperty observable) {
563 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
564 return observable instanceof UIThreadAware ? observable : new UIThreadAwareDoubleProperty(observable);
565 }
566
567 /**
568 * Creates an observable string property that notifies its listeners inside the UI thread.
569 *
570 * @param observable the observable string property to wrap.
571 *
572 * @return an observable string property.
573 */
574 @Nonnull
575 public static StringProperty uiThreadAwareStringProperty(@Nonnull StringProperty observable) {
576 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
577 return observable instanceof UIThreadAware ? observable : new UIThreadAwareStringProperty(observable);
578 }
579
580 /**
581 * Creates an observable boolean property that notifies its listeners inside the UI thread.
582 *
583 * @param observable the observable boolean property to wrap.
584 *
585 * @return an observable boolean property.
586 */
587 @Nonnull
588 public static Property<Boolean> uiThreadAwarePropertyBoolean(@Nonnull Property<Boolean> observable) {
589 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
590 return observable instanceof UIThreadAware ? observable : new UIThreadAwarePropertyBoolean(observable);
591 }
592
593 /**
594 * Creates an observable integer property that notifies its listeners inside the UI thread.
595 *
596 * @param observable the observable integer property to wrap.
597 *
598 * @return an observable integer property.
599 */
600 @Nonnull
601 public static Property<Integer> uiThreadAwarePropertyInteger(@Nonnull Property<Integer> observable) {
602 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
603 return observable instanceof UIThreadAware ? observable : new UIThreadAwarePropertyInteger(observable);
604 }
605
606 /**
607 * Creates an observable long property that notifies its listeners inside the UI thread.
608 *
609 * @param observable the observable long property to wrap.
610 *
611 * @return an observable long property.
612 */
613 @Nonnull
614 public static Property<Long> uiThreadAwarePropertyLong(@Nonnull Property<Long> observable) {
615 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
616 return observable instanceof UIThreadAware ? observable : new UIThreadAwarePropertyLong(observable);
617 }
618
619 /**
620 * Creates an observable float property that notifies its listeners inside the UI thread.
621 *
622 * @param observable the observable float property to wrap.
623 *
624 * @return an observable float property.
625 */
626 @Nonnull
627 public static Property<Float> uiThreadAwarePropertyFloat(@Nonnull Property<Float> observable) {
628 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
629 return observable instanceof UIThreadAware ? observable : new UIThreadAwarePropertyFloat(observable);
630 }
631
632 /**
633 * Creates an observable double property that notifies its listeners inside the UI thread.
634 *
635 * @param observable the observable double property to wrap.
636 *
637 * @return an observable double property.
638 */
639 @Nonnull
640 public static Property<Double> uiThreadAwarePropertyDouble(@Nonnull Property<Double> observable) {
641 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
642 return observable instanceof UIThreadAware ? observable : new UIThreadAwarePropertyDouble(observable);
643 }
644
645 /**
646 * Creates an observable string property that notifies its listeners inside the UI thread.
647 *
648 * @param observable the observable string property to wrap.
649 *
650 * @return an observable string property.
651 */
652 @Nonnull
653 public static Property<String> uiThreadAwarePropertyString(@Nonnull Property<String> observable) {
654 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
655 return observable instanceof UIThreadAware ? observable : new UIThreadAwarePropertyString(observable);
656 }
657
658 /**
659 * Creates an observable object property that notifies its listeners inside the UI thread.
660 *
661 * @param observable the observable object property to wrap.
662 *
663 * @return an observable object property.
664 */
665 @Nonnull
666 public static <T> ObjectProperty<T> uiThreadAwareObjectProperty(@Nonnull final ObjectProperty<T> observable) {
667 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
668 return observable instanceof UIThreadAware ? observable : new UIThreadAwareObjectProperty<>(observable);
669 }
670
671 /**
672 * Creates an observable list property that notifies its listeners inside the UI thread.
673 *
674 * @param observable the observable list property to wrap.
675 *
676 * @return an observable list property.
677 */
678 @Nonnull
679 public static <E> ListProperty<E> uiThreadAwareListProperty(@Nonnull ListProperty<E> observable) {
680 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
681 return observable instanceof UIThreadAware ? observable : new UIThreadAwareListProperty<>(observable);
682 }
683
684 /**
685 * Creates an observable set property that notifies its seteners inside the UI thread.
686 *
687 * @param observable the observable set property to wrap.
688 *
689 * @return an observable set property.
690 */
691 @Nonnull
692 public static <E> SetProperty<E> uiThreadAwareSetProperty(@Nonnull SetProperty<E> observable) {
693 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
694 return observable instanceof UIThreadAware ? observable : new UIThreadAwareSetProperty<>(observable);
695 }
696
697 /**
698 * Creates an observable map property that notifies its listeners inside the UI thread.
699 *
700 * @param observable the observable map property to wrap.
701 *
702 * @return an observable map property.
703 */
704 @Nonnull
705 public static <K, V> MapProperty<K, V> uiThreadAwareMapProperty(@Nonnull MapProperty<K, V> observable) {
706 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
707 return observable instanceof UIThreadAware ? observable : new UIThreadAwareMapProperty<>(observable);
708 }
709
710 /**
711 * Creates an observable value that notifies its listeners inside the UI thread.
712 *
713 * @param observable the observable to wrap.
714 *
715 * @return an observable value.
716 */
717 @Nonnull
718 public static <T> ObservableValue<T> uiThreadAwareObservable(@Nonnull final ObservableValue<T> observable) {
719 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
720 return observable instanceof UIThreadAware ? observable : new UIThreadAwareObservableValue<>(observable);
721 }
722
723 /**
724 * Creates an observable string value that notifies its listeners inside the UI thread.
725 *
726 * @param observable the observable string to wrap.
727 *
728 * @return an observable string value.
729 */
730 @Nonnull
731 public static ObservableStringValue uiThreadAwareObservableString(@Nonnull final ObservableStringValue observable) {
732 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
733 return observable instanceof UIThreadAware ? observable : new UIThreadAwareObservableStringValue(observable);
734 }
735
736 /**
737 * Creates an observable boolean value that notifies its listeners inside the UI thread.
738 *
739 * @param observable the observable boolean to wrap.
740 *
741 * @return an observable boolean value.
742 */
743 @Nonnull
744 public static ObservableBooleanValue uiThreadAwareObservableBoolean(@Nonnull final ObservableBooleanValue observable) {
745 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
746 return observable instanceof UIThreadAware ? observable : new UIThreadAwareObservableBooleanValue(observable);
747 }
748
749 /**
750 * Creates an observable integer value that notifies its listeners inside the UI thread.
751 *
752 * @param observable the observable integer to wrap.
753 *
754 * @return an observable integer value.
755 */
756 @Nonnull
757 public static ObservableIntegerValue uiThreadAwareObservableInteger(@Nonnull final ObservableIntegerValue observable) {
758 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
759 return observable instanceof UIThreadAware ? observable : new UIThreadAwareObservableIntegerValue(observable);
760 }
761
762 /**
763 * Creates an observable long value that notifies its listeners inside the UI thread.
764 *
765 * @param observable the observable long to wrap.
766 *
767 * @return an observable long value.
768 */
769 @Nonnull
770 public static ObservableLongValue uiThreadAwareObservableLong(@Nonnull final ObservableLongValue observable) {
771 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
772 return observable instanceof UIThreadAware ? observable : new UIThreadAwareObservableLongValue(observable);
773 }
774
775 /**
776 * Creates an observable float value that notifies its listeners inside the UI thread.
777 *
778 * @param observable the observable float to wrap.
779 *
780 * @return an observable float value.
781 */
782 @Nonnull
783 public static ObservableFloatValue uiThreadAwareObservableFloat(@Nonnull final ObservableFloatValue observable) {
784 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
785 return observable instanceof UIThreadAware ? observable : new UIThreadAwareObservableFloatValue(observable);
786 }
787
788 /**
789 * Creates an observable double value that notifies its listeners inside the UI thread.
790 *
791 * @param observable the observable double to wrap.
792 *
793 * @return an observable double value.
794 */
795 @Nonnull
796 public static ObservableDoubleValue uiThreadAwareObservableDouble(@Nonnull final ObservableDoubleValue observable) {
797 requireNonNull(observable, ERROR_OBSERVABLE_NULL);
798 return observable instanceof UIThreadAware ? observable : new UIThreadAwareObservableDoubleValue(observable);
799 }
800 }
|