org.reactfx.EventStream Java Examples

The following examples show how to use org.reactfx.EventStream. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ReactfxUtil.java    From pmd-designer with BSD 2-Clause "Simplified" License 6 votes vote down vote up
/**
 * Converts an event stream to a val, that always holds the latest
 * emitted value of the stream.
 */
public static <T> Val<T> latestValue(EventStream<T> values) {
    return new ValBase<T>() {
        private T currentVal;

        @Override
        protected Subscription connect() {
            return values.subscribe(t -> {
                currentVal = t;
                invalidate();
            });
        }

        @Override
        protected T computeValue() {
            return currentVal;
        }
    };
}
 
Example #2
Source File: MovingImageView.java    From neural-style-gui with GNU General Public License v3.0 6 votes vote down vote up
private void setupListeners() {
    ObjectProperty<Point2D> mouseDown = new SimpleObjectProperty<>();

    EventStreams.eventsOf(imageView, MouseEvent.MOUSE_PRESSED).subscribe(e -> {
        Point2D mousePress = imageViewToImage(new Point2D(e.getX(), e.getY()));
        mouseDown.set(mousePress);
    });

    EventStreams.eventsOf(imageView, MouseEvent.MOUSE_DRAGGED).subscribe(e -> {
        Point2D dragPoint = imageViewToImage(new Point2D(e.getX(), e.getY()));
        shift(dragPoint.subtract(mouseDown.get()));
        mouseDown.set(imageViewToImage(new Point2D(e.getX(), e.getY())));
    });

    EventStream<ScrollEvent> scrollEvents = EventStreams.eventsOf(imageView, ScrollEvent.SCROLL);
    EventStream<ScrollEvent> scrollEventsUp = scrollEvents.filter(scrollEvent -> scrollEvent.getDeltaY() < 0);
    EventStream<ScrollEvent> scrollEventsDown = scrollEvents.filter(scrollEvent -> scrollEvent.getDeltaY() > 0);
    scrollEventsUp.subscribe(scrollEvent -> scale = Math.min(scale + 0.25, 3));
    scrollEventsDown.subscribe(scrollEvent -> scale = Math.max(scale - 0.25, 0.25));
    EventStreams.merge(scrollEventsUp, scrollEventsDown).subscribe(scrollEvent -> scaleImageViewport(scale));

    EventStreams.eventsOf(imageView, MouseEvent.MOUSE_CLICKED)
            .filter(mouseEvent -> mouseEvent.getClickCount() == 2)
            .subscribe(mouseEvent -> fitToView());
}
 
Example #3
Source File: EventLoggerImpl.java    From pmd-designer with BSD 2-Clause "Simplified" License 6 votes vote down vote up
public EventLoggerImpl(DesignerRoot designerRoot) {
    this.designerRoot = designerRoot; // we have to be careful with initialization order here

    EventStream<LogEntry> onlyParseException = deleteOnSignal(latestEvent, PARSE_EXCEPTION, PARSE_OK);
    EventStream<LogEntry> onlyXPathException = deleteOnSignal(latestEvent, XPATH_EVALUATION_EXCEPTION, XPATH_OK);

    EventStream<LogEntry> otherExceptions =
        filterOnCategory(latestEvent, true, PARSE_EXCEPTION, XPATH_EVALUATION_EXCEPTION, SELECTION_EVENT_TRACING)
            .filter(it -> isDeveloperMode() || !it.getCategory().isInternal());

    // none of this is done if developer mode isn't enabled because then those events aren't even pushed in the first place
    EventStream<LogEntry> reducedTraces = ReactfxUtil.reduceEntangledIfPossible(
        latestEvent.filter(LogEntry::isTrace),
        (a, b) -> Objects.equals(a.messageProperty().getValue(), b.messageProperty().getValue()),
        LogEntry::appendMessage,
        EVENT_TRACING_REDUCTION_DELAY
    );

    EventStreams.merge(reducedTraces, onlyParseException, otherExceptions, onlyXPathException)
                .distinct()
                .subscribe(fullLog::add);
}
 
Example #4
Source File: Val.java    From ReactFX with BSD 2-Clause "Simplified" License 6 votes vote down vote up
static <T> Val<T> create(
        Supplier<? extends T> computeValue,
        EventStream<?> invalidations) {
    return new ValBase<T>() {

        @Override
        protected Subscription connect() {
            return invalidations.subscribe(x -> invalidate());
        }

        @Override
        protected T computeValue() {
            return computeValue.get();
        }
    };
}
 
Example #5
Source File: UndoManagerImpl.java    From UndoFX with BSD 2-Clause "Simplified" License 6 votes vote down vote up
public UndoManagerImpl(
        ChangeQueue<C> queue,
        Function<? super C, ? extends C> invert,
        Consumer<C> apply,
        BiFunction<C, C, Optional<C>> merge,
        Predicate<C> isIdentity,
        EventStream<C> changeSource,
        Duration preventMergeDelay) {
    this.queue = queue;
    this.invert = invert;
    this.apply = apply;
    this.merge = merge;
    this.isIdentity = isIdentity;
    this.mark = queue.getCurrentPosition();

    Subscription mainSub = changeSource.subscribe(this::changeObserved);

    if (preventMergeDelay.isZero() || preventMergeDelay.isNegative()) {
        subscription = mainSub;
    } else {
        Subscription sub2 = changeSource.successionEnds(preventMergeDelay).subscribe(ignore -> preventMerge());
        subscription = mainSub.and(sub2);
    }
}
 
Example #6
Source File: CaretNode.java    From RichTextFX with BSD 2-Clause "Simplified" License 5 votes vote down vote up
private static EventStream<Boolean> booleanPulse(javafx.util.Duration javafxDuration, EventStream<?> restartImpulse) {
    Duration duration = Duration.ofMillis(Math.round(javafxDuration.toMillis()));
    EventStream<?> ticks = EventStreams.restartableTicks(duration, restartImpulse);
    return StateMachine.init(false)
            .on(restartImpulse.withDefaultEvent(null)).transition((state, impulse) -> true)
            .on(ticks).transition((state, tick) -> !state)
            .toStateStream();
}
 
Example #7
Source File: UndoManagerFactory.java    From UndoFX with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * Creates an {@link UndoManager} with bounded history.
 * When at full capacity, a new change will cause the oldest change to be forgotten.
 *
 * <p>For description of the remaining parameters, see
 * {@link #createMultiChangeUM(EventStream, Function, Consumer, BiFunction, Predicate, Duration)}.</p>
 *
 * @param capacity maximum number of changes the returned UndoManager can store
 */
public static <C> UndoManager<List<C>> fixedSizeHistoryMultiChangeUM(
        EventStream<List<C>> changeStream,
        Function<? super C, ? extends C> invert,
        Consumer<List<C>> apply,
        BiFunction<C, C, Optional<C>> merge,
        Predicate<C> isIdentity,
        Duration preventMergeDelay,
        int capacity) {
    ChangeQueue<List<C>> queue = new FixedSizeChangeQueue<>(capacity);
    return new MultiChangeUndoManagerImpl<>(queue, invert, apply, merge, isIdentity, changeStream, preventMergeDelay);
}
 
Example #8
Source File: MouseStationaryHelper.java    From RichTextFX with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * Returns an {@link EventStream} that emits a {@link Point2D} whenever the mouse becomes stationary
 * over the helper's node and emits a {@code null} value whenever the mouse moves after being stationary.
 */
public EventStream<Either<Point2D, Void>> events(Duration delay) {
    EventStream<MouseEvent> mouseEvents = eventsOf(node, MouseEvent.ANY);
    EventStream<Point2D> stationaryPositions = mouseEvents
            .successionEnds(delay)
            .filter(e -> e.getEventType() == MOUSE_MOVED)
            .map(e -> new Point2D(e.getX(), e.getY()));
    EventStream<Void> stoppers = mouseEvents.supply((Void) null);
    return stationaryPositions.or(stoppers).distinct();
}
 
Example #9
Source File: UndoManagerFactory.java    From UndoFX with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * Creates an {@link UndoManager} with unlimited history.
 *
 * For description of parameters, see
 * {@link #createMultiChangeUM(EventStream, Function, Consumer, BiFunction, Predicate, Duration)}.
 */
public static <C> UndoManager<List<C>> unlimitedHistoryMultiChangeUM(
        EventStream<List<C>> changeStream,
        Function<? super C, ? extends C> invert,
        Consumer<List<C>> apply,
        BiFunction<C, C, Optional<C>> merge,
        Predicate<C> isIdentity,
        Duration preventMergeDelay) {
    ChangeQueue<List<C>> queue = new UnlimitedChangeQueue<>();
    return new MultiChangeUndoManagerImpl<>(queue, invert, apply, merge, isIdentity, changeStream, preventMergeDelay);
}
 
Example #10
Source File: EventLoggerImpl.java    From pmd-designer with BSD 2-Clause "Simplified" License 5 votes vote down vote up
private static EventStream<LogEntry> deleteOnSignal(EventStream<LogEntry> input, Category normal, Category deleteSignal) {
    return VetoableEventStream.vetoableFrom(
        filterOnCategory(input, false, normal, deleteSignal),
        (maybeVetoable) -> maybeVetoable.getCategory() == normal,
        (pending, maybeVeto) -> maybeVeto.getCategory() == deleteSignal,
        (a, b) -> b,
        PARSE_EXCEPTION_REDUCTION_DELAY
    );
}
 
Example #11
Source File: LiveList.java    From ReactFX with BSD 2-Clause "Simplified" License 5 votes vote down vote up
static <E> EventStream<QuasiListChange<? extends E>> quasiChangesOf(
        ObservableList<E> list) {
    if(list instanceof LiveList) {
        LiveList<E> lst = (LiveList<E>) list;
        return lst.quasiChanges();
    } else {
        return new EventStreamBase<QuasiListChange<? extends E>>() {
            @Override
            protected Subscription observeInputs() {
                return LiveList.<E>observeQuasiChanges(list, this::emit);
            }
        };
    }
}
 
Example #12
Source File: LiveList.java    From ReactFX with BSD 2-Clause "Simplified" License 5 votes vote down vote up
default EventStream<QuasiListModification<? extends E>> quasiModifications() {
    return new EventStreamBase<QuasiListModification<? extends E>>() {
        @Override
        protected Subscription observeInputs() {
            return observeQuasiModifications(this::emit);
        }
    };
}
 
Example #13
Source File: Val.java    From ReactFX with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * Returns a stream of invalidated values, which emits the invalidated value
 * (i.e. the old value) on each invalidation of this observable value.
 */
default EventStream<T> invalidations() {
    return new EventStreamBase<T>() {
        @Override
        protected Subscription observeInputs() {
            return observeInvalidations(this::emit);
        }
    };
}
 
Example #14
Source File: SimplePopups.java    From pmd-designer with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * Show a transient popup with a message, to let the user know an action
 * was performed.
 *
 * @param owner Node next to which the popup will be shown
 * @return
 */
public static EventStream<?> showActionFeedback(@NonNull Node owner,
                                                @Nullable Node graphic,
                                                @NonNull String message,
                                                double offsetX,
                                                boolean stick,
                                                String... cssClasses) {

    Popup popup = new Popup();
    Label label = new Label(message, graphic);
    StackPane pane = new StackPane();

    DesignerUtil.addCustomStyleSheets(pane, "designer");
    pane.getStyleClass().addAll("action-feedback");
    pane.getStyleClass().addAll(cssClasses);

    pane.getChildren().addAll(label);
    popup.getContent().addAll(pane);

    Animation fadeTransition = stick ? fadeInAnimation(pane) : bounceFadeAnimation(pane);
    EventSource<?> closeTick = new EventSource<>();
    if (stick) {
        pane.setOnMouseClicked(evt -> {
            popup.hide();
            closeTick.push(null);
        });
    } else {
        fadeTransition.setOnFinished(e -> {
            popup.hide();
            closeTick.push(null);
        });
    }

    popup.setOnShowing(e -> fadeTransition.play());

    Bounds screenBounds = owner.localToScreen(owner.getBoundsInLocal());
    popup.show(owner, screenBounds.getMaxX() + offsetX, screenBounds.getMinY());
    return closeTick;
}
 
Example #15
Source File: UndoManagerFactory.java    From UndoFX with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * Creates an {@link UndoManager} with unlimited history.
 *
 * For description of parameters, see
 * {@link #createMultiChangeUM(EventStream, Function, Consumer, BiFunction, Predicate, Duration)}.
 */
public static <C> UndoManager<List<C>> unlimitedHistoryMultiChangeUM(
        EventStream<List<C>> changeStream,
        Function<? super C, ? extends C> invert,
        Consumer<List<C>> apply) {
    return unlimitedHistoryMultiChangeUM(changeStream, invert, apply, (c1, c2) -> Optional.empty());
}
 
Example #16
Source File: SyntaxHighlightingCodeArea.java    From pmd-designer with BSD 2-Clause "Simplified" License 5 votes vote down vote up
private Subscription subscribeSyntaxHighlighting(EventStream<?> ticks, EventStream<?> canceller, SyntaxHighlighter highlighter) {
    // captured in the closure, shutdown when unsubscribing
    final ExecutorService executorService = Executors.newSingleThreadExecutor(
        r -> new Thread(r, "Code-area-" + this.hashCode() + "-"
            + highlighter.getLanguageTerseName() + "-highlighter"));
    return ticks.successionEnds(TEXT_CHANGE_DELAY)
                .supplyTask(() -> computeHighlightingAsync(executorService, highlighter, this.getText()))
                .awaitLatest(ticks.or(canceller))
                .filterMap(t -> {
                    t.ifFailure(Throwable::printStackTrace);
                    return t.toOptional();
                })
                .subscribe(this::setCurrentSyntaxHighlight)
                .and(executorService::shutdownNow);
}
 
Example #17
Source File: VetoableEventStream.java    From pmd-designer with BSD 2-Clause "Simplified" License 5 votes vote down vote up
private VetoableEventStream(
    EventStream<I> input,
    BiFunction<I, I, I> vetoableReduction,
    Predicate<I> isVetoable,
    BiPredicate<I, I> isVeto,
    Function<Runnable, Timer> timerFactory) {

    this.input = input;
    this.vetoableReduction = vetoableReduction;
    this.isVetoable = isVetoable;
    this.isVetoSignal = isVeto;
    this.timer = timerFactory.apply(this::handleTimeout);
}
 
Example #18
Source File: MessageChannel.java    From pmd-designer with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * Returns a stream of messages to be processed by the given component.
 *
 * @param component Component listening to the channel
 *
 * @return A stream of messages
 */
public EventStream<T> messageStream(boolean alwaysHandle,
                                    ApplicationComponent component) {
    // Eliminate duplicate messages in close succession.
    // TreeView selection is particularly shitty in that regard because
    // it emits many events for what corresponds to one click

    // This relies on the equality of two messages, so equals and hashcode
    // must be used correctly.
    return ReactfxUtil.distinctBetween(channel, Duration.ofMillis(100))
                      .hook(message -> logMessageTrace(component, message, () -> ""))
                      .filter(message -> alwaysHandle || !component.equals(message.getOrigin()))
                      .map(Message::getContent);
}
 
Example #19
Source File: UndoManagerFactory.java    From UndoFX with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * Creates an {@link UndoManager} with unlimited history.
 *
 * For description of parameters, see
 * {@link #createSingleChangeUM(EventStream, Function, Consumer, BiFunction, Predicate, Duration)}.
 */
public static <C> UndoManager<C> unlimitedHistorySingleChangeUM(
        EventStream<C> changeStream,
        Function<? super C, ? extends C> invert,
        Consumer<C> apply,
        BiFunction<C, C, Optional<C>> merge,
        Predicate<C> isIdentity) {
    return unlimitedHistorySingleChangeUM(changeStream, invert, apply, merge, isIdentity, Duration.ZERO);
}
 
Example #20
Source File: VetoableEventStream.java    From pmd-designer with BSD 2-Clause "Simplified" License 5 votes vote down vote up
public static <I> AwaitingEventStream<I> vetoableFrom(EventStream<I> input,
                                                      Predicate<I> isVetoable,
                                                      BiPredicate<I, I> isVeto,
                                                      BiFunction<I, I, I> vetoableReduction,
                                                      Duration vetoPeriod) {
    return vetoableFrom(input, isVetoable, isVeto, vetoableReduction, ReactfxUtil.defaultTimerFactory(vetoPeriod));
}
 
Example #21
Source File: UndoManagerFactory.java    From UndoFX with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * Creates an {@link UndoManager} with unlimited history.
 *
 * For description of parameters, see
 * {@link #createSingleChangeUM(EventStream, Function, Consumer, BiFunction, Predicate, Duration)}.
 */
public static <C> UndoManager<C> unlimitedHistorySingleChangeUM(
        EventStream<C> changeStream,
        Function<? super C, ? extends C> invert,
        Consumer<C> apply) {
    return unlimitedHistorySingleChangeUM(changeStream, invert, apply, (c1, c2) -> Optional.empty());
}
 
Example #22
Source File: MultiChangeUndoManagerImpl.java    From UndoFX with BSD 2-Clause "Simplified" License 4 votes vote down vote up
public MultiChangeUndoManagerImpl(
        ChangeQueue<List<C>> queue,
        Function<? super C, ? extends C> changeInvert,
        Consumer<List<C>> apply,
        BiFunction<C, C, Optional<C>> changeMerge,
        Predicate<C> changeIsIdentity,
        EventStream<List<C>> changeSource,
        Duration preventMergeDelay) {
    super(
            queue,
            list -> {
                List<C> l = new ArrayList<>(list.size());
                // invert the contents of the list
                // and store them in reversed order
                for (int i = list.size() - 1; i >= 0; i--) {
                    l.add(changeInvert.apply(list.get(i)));
                }
                return l;
            },
            apply,
            (list1, list2) -> {
                // if one list is empty, return the other list
                if (list1.size() == 0) {
                    return Optional.of(list2);
                } else if (list2.size() == 0) {
                    return Optional.of(list1);
                }

                // if both are the same size and every corresponding element
                // can be merged, return a list with all merged items.
                // Otherwise, return Optional.empty()
                if (list1.size() == list2.size()) {
                    List<C> mergeList = new ArrayList<>(list1.size());
                    for (int i = 0; i < list1.size(); i++) {
                        C item1 = list1.get(i);
                        C item2 = list2.get(i);
                        Optional<C> merge = changeMerge.apply(item1, item2);
                        if (merge.isPresent()) {
                            mergeList.add(merge.get());
                        } else {
                            return Optional.empty();
                        }
                    }
                    return Optional.of(mergeList);
                } else {
                    return Optional.empty();
                }
            },
            list -> list.stream().allMatch(changeIsIdentity),
            changeSource,
            preventMergeDelay
    );
}
 
Example #23
Source File: PopupDemo.java    From RichTextFX with BSD 2-Clause "Simplified" License 4 votes vote down vote up
private Subscription feedVisibilityToLabelText(EventStream<Optional<Bounds>> boundsStream, BoundsPopup popup, String item) {
    return boundsStream
            .map(o -> o.isPresent() ? " is " : " is not ")
            .subscribe(visibilityStatus -> popup.setText(item + visibilityStatus + "within the viewport"));
}
 
Example #24
Source File: GenericStyledArea.java    From RichTextFX with BSD 2-Clause "Simplified" License 4 votes vote down vote up
private EventStream<MouseOverTextEvent> mouseOverTextEvents(ObservableSet<ParagraphBox<PS, SEG, S>> cells, Duration delay) {
    return merge(cells, c -> c.stationaryIndices(delay).map(e -> e.unify(
            l -> l.map((pos, charIdx) -> MouseOverTextEvent.beginAt(c.localToScreen(pos), getParagraphOffset(c.getIndex()) + charIdx)),
            r -> MouseOverTextEvent.end())));
}
 
Example #25
Source File: PropertyDescriptorSpec.java    From pmd-designer with BSD 2-Clause "Simplified" License 4 votes vote down vote up
/**
 * Pushes an event every time the rule owning this property needs to be re-evaluated.
 */
public EventStream<?> modificationTicks() {
    return nameProperty().values()
                         .or(valueProperty().values())
                         .or(typeIdProperty().values());
}
 
Example #26
Source File: ContentEditor.java    From milkman with MIT License 4 votes vote down vote up
private void setupCodeArea() {
		codeArea = new CodeArea();
//		codeArea.setWrapText(true);
		setupParagraphGraphics();
		EventStream<Object> highLightTrigger = EventStreams.merge(codeArea.multiPlainChanges(),
				EventStreams.changesOf(highlighters.getSelectionModel().selectedItemProperty()),
				EventStreams.eventsOf(format, MouseEvent.MOUSE_CLICKED));


		//behavior of TAB: 2 spaces, allow outdention via SHIFT-TAB, if cursor is at beginning
		Nodes.addInputMap(codeArea, InputMap.consume(
				EventPattern.keyPressed(KeyCode.TAB),
				e -> codeArea.replaceSelection("  ")
		));

		Nodes.addInputMap(codeArea, InputMap.consume(
				EventPattern.keyPressed(KeyCode.TAB, SHIFT_DOWN),
				e -> {
					var paragraph = codeArea.getParagraph(codeArea.getCurrentParagraph());
					var indentation = StringUtils.countStartSpaces(paragraph.getText());

					//is the cursor in the white spaces
					if (codeArea.getCaretColumn() <= indentation){
						var charsToRemove = Math.min(indentation, 2);

						codeArea.replaceText(new IndexRange(codeArea.getAbsolutePosition(codeArea.getCurrentParagraph(), 0),
								codeArea.getAbsolutePosition(codeArea.getCurrentParagraph(), (int) charsToRemove)),
								"");
					}
				}
		));

		// sync highlighting:
//		Subscription cleanupWhenNoLongerNeedIt = highLightTrigger
//				 .successionEnds(Duration.ofMillis(500))
//				 .subscribe(ignore -> {
//					System.out.println("Triggered highlight via end-of-succession");
//					 highlightCode();
//				 });

		// async highlighting:
		Subscription cleanupWhenNoLongerNeedIt = highLightTrigger.successionEnds(Duration.ofMillis(500))
				.supplyTask(this::highlightCodeAsync).awaitLatest(codeArea.multiPlainChanges()).filterMap(t -> {
					if (t.isSuccess()) {
						return Optional.of(t.get());
					} else {
						t.getFailure().printStackTrace();
						return Optional.empty();
					}
				}).subscribe(this::applyHighlighting);

		KeyCombination.Modifier controlKey = KeyCombination.CONTROL_DOWN;
		if (SystemUtils.IS_OS_MAC){
			controlKey = KeyCombination.META_DOWN;
		}
		val keyCombination = PlatformUtil.getControlKeyCombination(KeyCode.F);
		codeArea.setOnKeyPressed(e -> {
			if (keyCombination.match(e)) {
				focusSearch();
			}
		});
	}
 
Example #27
Source File: GenericBinding.java    From milkman with MIT License 4 votes vote down vote up
public EventStream<T> toStream(){
	//this instead of EventStream.nonNullValues bc we want to omit initial (artificial) value
	return EventStreams.changesOf(this).filterMap(c -> Optional.ofNullable(c.getNewValue()));
}
 
Example #28
Source File: XPathAutocompleteProvider.java    From pmd-designer with BSD 2-Clause "Simplified" License 4 votes vote down vote up
public void initialiseAutoCompletion() {

        // allows tab/enter completion
        EventStreams.eventsOf(autoCompletePopup, KeyEvent.ANY)
                    .filter(e -> !e.isConsumed())
                    .filter(e ->
                                // For some reason this has to be asymmetric
                                // Delivered events vary between JREs, as well as their properties
                                // This is the common denominator I found for JREs 8..10

                                // Only KEY_RELEASED events are delivered for ENTER
                                e.getEventType().equals(KeyEvent.KEY_RELEASED) && e.getCode() == KeyCode.ENTER
                                    // All KEY_TYPED, KEY_PRESSED, and KEY_RELEASED are delivered for TAB,
                                    // but we have to handle it before it inserts a \t so we catch KEY_PRESSED
                                    || e.getEventType().equals(KeyEvent.KEY_PRESSED) && e.getCode() == KeyCode.TAB

                    )
                    .conditionOn(autoCompletePopup.showingProperty())
                    .subscribe(e -> {
                        int focusIdx = getFocusIdx();
                        if (focusIdx == -1) {
                            focusIdx = 0;
                        }

                        if (focusIdx < autoCompletePopup.getItems().size()) {
                            autoCompletePopup.getItems().get(focusIdx).getOnAction().handle(new ActionEvent());
                        }
                        e.consume();
                    });

        EventStream<Integer> changesEventStream = myCodeArea.plainTextChanges()
                                                            // filter out copy paste
                                                            .filter(it -> it.getNetLength() == 1)
                                                            .map(characterChanges -> {
                                                                if (characterChanges.getRemoved().length() > 0) {
                                                                    return characterChanges.getRemovalEnd() - 1;
                                                                }
                                                                return characterChanges.getInsertionEnd();
                                                            });

        EventStream<Integer> keyCombo = EventStreams.eventsOf(myCodeArea, KeyEvent.KEY_PRESSED)
                                                    .filter(key -> key.isControlDown() && key.getCode().equals(KeyCode.SPACE))
                                                    .map(searchPoint -> myCodeArea.getCaretPosition());

        EventStreams.merge(keyCombo, changesEventStream)
                    .map(this::getInsertionPointAndQuery)
                    .hook(t -> {
                        if (t == null) {
                            autoCompletePopup.hide();
                        }
                    })
                    .filter(Objects::nonNull)
                    .subscribe(s -> showAutocompletePopup(s._1, s._2));
    }
 
Example #29
Source File: TestCaseListCell.java    From pmd-designer with BSD 2-Clause "Simplified" License 4 votes vote down vote up
@Override
public EventStream<?> additionalTicks() {
    return testCase.modificationTicks();
}
 
Example #30
Source File: SelectionImpl.java    From RichTextFX with BSD 2-Clause "Simplified" License 4 votes vote down vote up
private <T> void manageSubscription(EventStream<T> stream, Consumer<T> consumer) {
    manageSubscription(stream.subscribe(consumer));
}