use of org.reactfx.Subscription in project RichTextFX by FXMisc.
the class SubscribeableContentsObsSet method addSubscriber.
/**
* Subscribes to all current and future elements' internal changes in this set until either they are removed
* or this subscriber is removed by calling {@link Subscription#unsubscribe() unsubscribe} on the function's
* returned {@link Subscription}.
*/
public Subscription addSubscriber(Function<? super E, Subscription> subscriber) {
Objects.requireNonNull(subscriber);
subscribers.add(subscriber);
List<E> keys = new ArrayList<>(map.keySet());
keys.forEach(key -> {
List<Subscription> otherSubs = map.get(key);
Subscription sub = subscriber.apply(key);
otherSubs.add(sub);
map.put(key, otherSubs);
});
return () -> removeSubscriber(subscriber);
}
use of org.reactfx.Subscription in project RichTextFX by FXMisc.
the class SubscribeableContentsObsSetTest method adding_subscriber_and_removing_it_will_not_throw_exception.
@Test
public void adding_subscriber_and_removing_it_will_not_throw_exception() {
SubscribeableContentsObsSet<Integer> set = new SubscribeableContentsObsSet<>();
Subscription removeSubscriber = set.addSubscriber(i -> Subscription.EMPTY);
removeSubscriber.unsubscribe();
}
use of org.reactfx.Subscription in project RichTextFX by FXMisc.
the class SubscribeableContentsObsSetTest method adding_new_subscriber_when_list_has_contents_does_not_fire_change_event.
@Test
public void adding_new_subscriber_when_list_has_contents_does_not_fire_change_event() {
SubscribeableContentsObsSet<Integer> contentSet = new SubscribeableContentsObsSet<>();
contentSet.add(1);
contentSet.add(2);
contentSet.add(3);
SimpleBooleanProperty changeWasFired = new SimpleBooleanProperty(false);
Subscription removeChangeListener = contentSet.addChangeListener(change -> changeWasFired.set(true));
contentSet.addSubscriber(b -> Subscription.EMPTY);
assertFalse(changeWasFired.get());
// cleanup
removeChangeListener.unsubscribe();
}
use of org.reactfx.Subscription in project RichTextFX by FXMisc.
the class SubscribeableContentsObsSetTest method adding_subscriber_and_later_removing_it_will_unsubscribe_from_all_elements.
@Test
public void adding_subscriber_and_later_removing_it_will_unsubscribe_from_all_elements() {
SubscribeableContentsObsSet<BoxedProperty> contentSet = new SubscribeableContentsObsSet<>();
List<Integer> storageList = new LinkedList<>();
// when property is set to a new value, store the new value in storageList
Subscription removeSubscriber = contentSet.addSubscriber(b -> b.intValues.subscribe(storageList::add));
BoxedProperty box1 = new BoxedProperty(1);
BoxedProperty box2 = new BoxedProperty(2);
contentSet.add(box1);
contentSet.add(box2);
box1.addOne();
box2.addOne();
assertEquals(2, storageList.size());
storageList.clear();
removeSubscriber.unsubscribe();
box1.addOne();
box2.addOne();
assertEquals(0, storageList.size());
}
use of org.reactfx.Subscription in project RichTextFX by FXMisc.
the class PopupDemo method start.
@Override
public void start(Stage primaryStage) {
stage = primaryStage;
StringBuilder sb = new StringBuilder();
for (int i = 2; i < 100; i++) {
sb.append(String.valueOf(i)).append(" END\n");
}
InlineCssTextArea area = new InlineCssTextArea("Hello popup!\n" + sb.toString());
area.setWrapText(true);
VirtualizedScrollPane<InlineCssTextArea> vsPane = new VirtualizedScrollPane<>(area);
BoundsPopup caretPopup = new BoundsPopup("I am the caret popup button!");
BoundsPopup selectionPopup = new BoundsPopup("I am the selection popup button!");
VBox caretOptions = createPopupOptions(caretPopup, "Show/Hide caret-based popup", "Show/Hide popup even when caret is out of viewport");
VBox selectionOptions = createPopupOptions(selectionPopup, "Show/Hide selection-based popup", "Show/Hide popup even when selection is out of viewport");
BorderPane borderPane = new BorderPane();
borderPane.setTop(caretOptions);
borderPane.setCenter(vsPane);
borderPane.setBottom(selectionOptions);
primaryStage.setScene(new Scene(borderPane, 400, 500));
primaryStage.setTitle("Popup Demo");
primaryStage.show();
// ### Set up EventStreams
// update labels depending on whether item is within viewport
EventStream<Optional<Bounds>> caretBounds = nonNullValuesOf(area.caretBoundsProperty());
Subscription cBoundsSub = feedVisibilityToLabelText(caretBounds, caretPopup, "Caret");
EventStream<Optional<Bounds>> selectionBounds = nonNullValuesOf(area.selectionBoundsProperty());
Subscription sBoundsSub = feedVisibilityToLabelText(selectionBounds, selectionPopup, "Selection");
// set up event streams to update popups every time bounds change
double caretXOffset = 0;
double caretYOffset = 0;
double selectionXOffset = 30;
double selectionYOffset = 30;
Subscription caretPopupSub = EventStreams.combine(caretBounds, caretPopup.outsideViewportValues()).subscribe(tuple3 -> {
Optional<Bounds> opt = tuple3._1;
boolean showPopupWhenCaretOutside = tuple3._2;
if (opt.isPresent()) {
Bounds b = opt.get();
caretPopup.setX(b.getMaxX() + caretXOffset);
caretPopup.setY(b.getMaxY() + caretYOffset);
if (caretPopup.isHiddenTemporarily()) {
caretPopup.show(stage);
caretPopup.setHideTemporarily(false);
}
} else {
if (!showPopupWhenCaretOutside) {
caretPopup.hide();
caretPopup.setHideTemporarily(true);
}
}
});
Subscription selectionPopupSub = EventStreams.combine(selectionBounds, selectionPopup.outsideViewportValues()).subscribe(tuple3 -> {
Optional<Bounds> opt = tuple3._1;
boolean showPopupWhenSelectionOutside = tuple3._2;
if (opt.isPresent()) {
Bounds b = opt.get();
selectionPopup.setX(b.getMinX() + selectionXOffset + caretPopup.getWidth());
selectionPopup.setY(b.getMinY() + selectionYOffset);
if (selectionPopup.isHiddenTemporarily()) {
selectionPopup.show(stage);
selectionPopup.setHideTemporarily(false);
}
} else {
if (!showPopupWhenSelectionOutside) {
selectionPopup.hide();
selectionPopup.setHideTemporarily(true);
}
}
});
Subscription caretSubs = caretPopupSub.and(cBoundsSub);
Subscription selectionSubs = selectionPopupSub.and(sBoundsSub);
caretPopup.show(primaryStage);
selectionPopup.show(primaryStage);
area.moveTo(0);
area.requestFollowCaret();
}
Aggregations