ListenerManager { @NotNull public CompositeListener listenAll(@NotNull ObservableValue<?>... values) { CompositeListener listener = new CompositeListener(values); myCompositeListeners.add(listener); return listener; } ListenerManager();  ListenerManager(@NotNull BatchInvoker.Strategy invokeStrategy); void listen(@NotNull ObservableValue<?> src, @NotNull InvalidationListener listener); void listen(@NotNull final ObservableValue<T> src, @NotNull final Receiver<T> receiver); void listenAndFire(@NotNull ObservableValue<?> src, @NotNull InvalidationListener listener); void listenAndFire(@NotNull final ObservableValue<T> src, @NotNull final Receiver<T> receiver); @NotNull CompositeListener listenAll(@NotNull ObservableValue<?>... values); @NotNull CompositeListener listenAll(@NotNull Collection<? extends ObservableValue<?>> values); void release(@NotNull InvalidationListener listener); void release(@NotNull Receiver<?> receiver); void release(@NotNull ObservableValue<?> observable); void release(@NotNull Runnable listenAllRunnable); void releaseAll();  }
@Test public void listenAllWorks() throws Exception { TestInvokeStrategy testStrategy = new TestInvokeStrategy(); ListenerManager listeners = new ListenerManager(testStrategy); IntProperty x = new IntValueProperty(0); IntProperty y = new IntValueProperty(0); IntProperty w = new IntValueProperty(640); IntProperty h = new IntValueProperty(480); BoolProperty grayscale = new BoolValueProperty(false); CountingRunnable mockRepaint = new CountingRunnable(); listeners.listenAll(x, y, w, h, grayscale).with(mockRepaint); assertThat(mockRepaint.myRunCount).isEqualTo(0); w.set(1280); h.set(720); assertThat(mockRepaint.myRunCount).isEqualTo(0); testStrategy.updateOneStep(); assertThat(mockRepaint.myRunCount).isEqualTo(1); grayscale.set(true); testStrategy.updateOneStep(); assertThat(mockRepaint.myRunCount).isEqualTo(2); }