org.reactfx.value.Val Java Examples

The following examples show how to use org.reactfx.value.Val. 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
public static <K, V> Val<Map<K, V>> observableMapVal(ObservableMap<K, V> map) {
    return new ValBase<Map<K, V>>() {

        @Override
        protected Subscription connect() {
            MapChangeListener<K, V> listener = ch -> notifyObservers(new HashMap<>(map));
            map.addListener(listener);
            return () -> map.removeListener(listener);
        }

        @Override
        protected Map<K, V> computeValue() {
            return new HashMap<>(map);
        }
    };
}
 
Example #2
Source File: MarkdownTextArea.java    From markdown-writer-fx with BSD 2-Clause "Simplified" License 6 votes vote down vote up
public MarkdownTextArea() {
	super(
		/* initialParagraphStyle */ Collections.<String>emptyList(),
		/* applyParagraphStyle */ (paragraph, styleClasses) -> paragraph.getStyleClass().addAll(styleClasses),
		/* initialTextStyle */ Collections.<String>emptyList(),
		/* textOps */ SegmentOps.<Collection<String>>styledTextOps()._or(new EmbeddedImageOps<Collection<String>>(), (s1, s2) -> Optional.empty()),
		/* preserveStyle */ false,
		/* nodeFactory */ seg -> createNode(seg,
			(text, styleClasses) -> text.getStyleClass().addAll(styleClasses))
		);

	// compute scrollY
	scrollY = Val.create(() -> {
		double value = estimatedScrollYProperty().getValue().doubleValue();
		double maxValue = totalHeightEstimateProperty().getOrElse(0.).doubleValue() - getHeight();
		return (maxValue > 0) ? Math.min(Math.max(value / maxValue, 0), 1) : 0;
	}, estimatedScrollYProperty(), totalHeightEstimateProperty()).suspendable();
}
 
Example #3
Source File: ListRangeReductionTest.java    From ReactFX with BSD 2-Clause "Simplified" License 6 votes vote down vote up
@Test
public void test() {
    LiveList<Integer> list = new LiveArrayList<>(1, 2, 4);
    Var<IndexRange> range = Var.newSimpleVar(new IndexRange(0, 0));
    Val<Integer> rangeSum = list.reduceRange(range, (a, b) -> a + b);

    assertNull(rangeSum.getValue());

    List<Integer> observed = new ArrayList<>();
    rangeSum.values().subscribe(sum -> {
        observed.add(sum);
        if(sum == null) {
            range.setValue(new IndexRange(0, 2));
        } else if(sum == 3) {
            list.addAll(1, Arrays.asList(8, 16));
        } else if(sum == 9) {
            range.setValue(new IndexRange(2, 4));
        }
    });

    assertEquals(Arrays.asList(null, 3, 9, 18), observed);
}
 
Example #4
Source File: MemoizationListTest.java    From ReactFX with BSD 2-Clause "Simplified" License 6 votes vote down vote up
@Test
public void testMemoizedItemsChangeWithinForce() {
    LiveList<Integer> src = new LiveArrayList<>(1, 2, 4, 8, 16, 32);
    MemoizationList<Integer> memo1 = src.memoize();
    MemoizationList<Integer> memo2 = memo1.map(Function.identity()).memoize();
    Val<Integer> memo1Sum = memo1.memoizedItems().reduce((a, b) -> a + b).orElseConst(0);
    memo1Sum.addListener((obs, oldVal, newVal) -> memo2.forget(0, memo2.size()));

    List<Integer> memo2Mirror = new ArrayList<>();
    memo2.memoizedItems().observeModifications(mod -> {
        memo2Mirror.subList(mod.getFrom(), mod.getFrom() + mod.getRemovedSize()).clear();
        memo2Mirror.addAll(mod.getFrom(), mod.getAddedSubList());
        // the main part of this test is that it does not throw IndexOutOfBoundsException
    });
    memo2.force(3, 6);

    assertEquals(Arrays.asList(32), memo2Mirror);
}
 
Example #5
Source File: MutableTabPane.java    From pmd-designer with BSD 2-Clause "Simplified" License 6 votes vote down vote up
/** Makes the title unique w.r.t. already present tabs. */
private Val<String> uniqueNameBinding(Val<String> titleProperty, int tabIdx) {
    Binding<String> uniqueBinding = Bindings.createStringBinding(
        () -> {
            String title = titleProperty.getOrElse("Unnamed");
            int sameName = 0;
            LiveList<T> controllers = getControllers();
            for (int i = 0; i < controllers.size() && i < tabIdx; i++) {
                if (title.equals(controllers.get(i).titleProperty().getOrElse("Unnamed"))) {
                    sameName++;
                }

            }
            return sameName == 0 ? title : title + " (" + sameName + ")";
        },
        titleProperty,
        getTabs()
    );
    return Val.wrap(uniqueBinding);
}
 
Example #6
Source File: NodeSelectionSource.java    From pmd-designer with BSD 2-Clause "Simplified" License 6 votes vote down vote up
/**
 * Initialises this component. Must be called by the component somewhere.
 *
 * @param root                  Instance of the app. Should be the same as {@link #getDesignerRoot()},
 *                              but the parameter here is to make it clear that {@link #getDesignerRoot()}
 *                              must be initialized before this method is called.
 * @param mySelectionEvents     Stream of nodes that should push an event each time the user selects a node
 *                              from this control. The whole app will sync to this new selection.
 * @param alwaysHandleSelection Whether the component should handle selection events that originated from itself.
 * @return A Val reflecting the current global selection for the app.
 * Note that that Val is lazy and so if you don't subscribe to it or
 * {@linkplain Val#pin() pin it} you won't see updates!
 */
default Val<Node> initNodeSelectionHandling(DesignerRoot root,
                                            EventStream<? extends NodeSelectionEvent> mySelectionEvents,
                                            boolean alwaysHandleSelection) {
    MessageChannel<NodeSelectionEvent> channel = root.getService(DesignerRoot.NODE_SELECTION_CHANNEL);
    mySelectionEvents.subscribe(n -> channel.pushEvent(this, n));
    EventStream<NodeSelectionEvent> selection = channel.messageStream(alwaysHandleSelection, this);
    selection.subscribe(evt -> {
        try {
            setFocusNode(evt.selected, evt.options);
        } catch (Exception e) {
            logInternalException(e);
            printShortStackTrace(e);
            // don't rethrow so that an error by one source doesn't affect others
        }
    });
    return ReactfxUtil.latestValue(selection.map(it -> it.selected));
}
 
Example #7
Source File: NodeEditionCodeArea.java    From pmd-designer with BSD 2-Clause "Simplified" License 6 votes vote down vote up
public IntFunction<javafx.scene.Node> defaultLineNumberFactory() {
    IntFunction<javafx.scene.Node> base = LineNumberFactory.get(this);
    Val<Integer> activePar = Val.wrap(currentParagraphProperty());

    return idx -> {

        javafx.scene.Node label = base.apply(idx);

        activePar.conditionOnShowing(label)
                 .values()
                 .subscribe(p -> label.pseudoClassStateChanged(PseudoClass.getPseudoClass("has-caret"), idx == p));

        // adds a pseudo class if part of the focus node appears on this line
        currentFocusNode.conditionOnShowing(label)
                        .values()
                        .subscribe(n -> label.pseudoClassStateChanged(PseudoClass.getPseudoClass("is-focus-node"),
                                                                      n != null && idx + 1 <= n.getEndLine() && idx + 1 >= n.getBeginLine()));

        return label;
    };
}
 
Example #8
Source File: ControlUtil.java    From pmd-designer with BSD 2-Clause "Simplified" License 6 votes vote down vote up
/**
 * Make a list view fit precisely the height of its items.
 *
 * @param view            The listview to configure
 * @param fixedCellHeight The cell height to use, a good default is 24
 */
public static void makeTableViewFitToChildren(TableView<?> view, double fixedCellHeight) {
    view.setFixedCellSize(fixedCellHeight);

    subscribeOnSkin(view, skin -> {

        Region header = (Region) skin.getNode().lookup(".nested-column-header");

        view.maxHeightProperty().bind(
            Val.wrap(view.itemsProperty())
               .flatMap(LiveList::sizeOf).map(it -> header.prefHeight(-1) + (it == 0 ? fixedCellHeight
                                                                                     : it * fixedCellHeight + 5))
        );

        return view.maxHeightProperty()::unbind;
    });

}
 
Example #9
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 #10
Source File: LiveList.java    From ReactFX with BSD 2-Clause "Simplified" License 5 votes vote down vote up
@Experimental
static <E> Val<E> reduceRange(
        ObservableList<E> list,
        ObservableValue<IndexRange> range,
        BinaryOperator<E> reduction) {
    return new ListRangeReduction<>(list, range, reduction);
}
 
Example #11
Source File: LiveList.java    From ReactFX with BSD 2-Clause "Simplified" License 5 votes vote down vote up
@Experimental
static <E, T> Val<T> collapseDynamic(
        ObservableList<? extends E> list,
        ObservableValue<? extends Function<? super List<E>, ? extends T>> f) {
    return Val.create(
            () -> f.getValue().apply(Collections.unmodifiableList(list)),
            list, f);
}
 
Example #12
Source File: ScaledVirtualized.java    From Flowless with BSD 2-Clause "Simplified" License 5 votes vote down vote up
public ScaledVirtualized(V content) {
    super();
    this.content = content;
    getChildren().add(content);
    getTransforms().add(zoom);

    estHeight = Val.combine(
            content.totalHeightEstimateProperty(),
            zoom.yProperty(),
            (estHeight, scaleFactor) -> estHeight * scaleFactor.doubleValue()
    );
    estWidth = Val.combine(
            content.totalWidthEstimateProperty(),
            zoom.xProperty(),
            (estWidth, scaleFactor) -> estWidth * scaleFactor.doubleValue()
    );
    estScrollX = Var.mapBidirectional(
            content.estimatedScrollXProperty(),
            scrollX -> scrollX * zoom.getX(),
            scrollX -> scrollX / zoom.getX()
    );
    estScrollY = Var.mapBidirectional(
            content.estimatedScrollYProperty(),
            scrollY -> scrollY * zoom.getY(),
            scrollY -> scrollY / zoom.getY()
    );

    zoom.xProperty()     .addListener((obs, ov, nv) -> requestLayout());
    zoom.yProperty()     .addListener((obs, ov, nv) -> requestLayout());
    zoom.zProperty()     .addListener((obs, ov, nv) -> requestLayout());
    zoom.pivotXProperty().addListener((obs, ov, nv) -> requestLayout());
    zoom.pivotYProperty().addListener((obs, ov, nv) -> requestLayout());
    zoom.pivotZProperty().addListener((obs, ov, nv) -> requestLayout());
}
 
Example #13
Source File: AttributeNameTableCell.java    From pmd-designer with BSD 2-Clause "Simplified" License 5 votes vote down vote up
public AttributeNameTableCell() {
    getStyleClass().add("attribute-name");

    Val.wrap(tableRowProperty())
       .flatMap(Cell::itemProperty)
       .values()
       .distinct()
        .subscribe(this::updateAttr);
}
 
Example #14
Source File: ListReductionTest.java    From ReactFX with BSD 2-Clause "Simplified" License 5 votes vote down vote up
@Test
public void testWhenUnbound() {
    ObservableList<Integer> list = FXCollections.observableArrayList(1, 1, 1, 1, 1);
    Val<Integer> sum = LiveList.reduce(list, (a, b) -> a + b);

    assertEquals(5, sum.getValue().intValue());

    list.addAll(2, Arrays.asList(2, 2));
    assertEquals(9, sum.getValue().intValue());

    list.clear();
    assertNull(sum.getValue());
}
 
Example #15
Source File: VirtualFlow.java    From Flowless with BSD 2-Clause "Simplified" License 5 votes vote down vote up
private VirtualFlow(
        ObservableList<T> items,
        Function<? super T, ? extends C> cellFactory,
        OrientationHelper orientation,
        Gravity gravity) {
    this.getStyleClass().add("virtual-flow");
    this.items = items;
    this.orientation = orientation;
    this.cellListManager = new CellListManager<>(this, items, cellFactory);
    this.gravity.set(gravity);
    MemoizationList<C> cells = cellListManager.getLazyCellList();
    this.sizeTracker = new SizeTracker(orientation, layoutBoundsProperty(), cells);
    this.cellPositioner = new CellPositioner<>(cellListManager, orientation, sizeTracker);
    this.navigator = new Navigator<>(cellListManager, cellPositioner, orientation, this.gravity, sizeTracker);

    getChildren().add(navigator);
    clipProperty().bind(Val.map(
            layoutBoundsProperty(),
            b -> new Rectangle(b.getWidth(), b.getHeight())));

    lengthOffsetEstimate = sizeTracker.lengthOffsetEstimateProperty().asVar(this::setLengthOffset);

    // scroll content by mouse scroll
    this.addEventHandler(ScrollEvent.ANY, se -> {
        scrollXBy(-se.getDeltaX());
        scrollYBy(-se.getDeltaY());
        se.consume();
    });
}
 
Example #16
Source File: ParagraphBox.java    From RichTextFX with BSD 2-Clause "Simplified" License 5 votes vote down vote up
ParagraphBox(Paragraph<PS, SEG, S> par, BiConsumer<TextFlow, PS> applyParagraphStyle,
             Function<StyledSegment<SEG, S>, Node> nodeFactory) {
    this.getStyleClass().add("paragraph-box");
    this.text = new ParagraphText<>(par, nodeFactory);
    applyParagraphStyle.accept(this.text, par.getParagraphStyle());
    
    // start at -1 so that the first time it is displayed, the caret at pos 0 is not
    // accidentally removed from its parent and moved to this node's ParagraphText
    // before this node gets updated to its real index and therefore removes
    // caret from the SceneGraph completely
    this.index = Var.newSimpleVar(-1);

    getChildren().add(text);
    graphic = Val.combine(
            graphicFactory,
            this.index,
            (f, i) -> f != null && i > -1 ? f.apply(i) : null);
    graphic.addListener((obs, oldG, newG) -> {
        if(oldG != null) {
            getChildren().remove(oldG);
        }
        if(newG != null) {
            getChildren().add(newG);
        }
    });
    graphicOffset.addListener(obs -> requestLayout());
}
 
Example #17
Source File: NodeEditionCodeArea.java    From pmd-designer with BSD 2-Clause "Simplified" License 5 votes vote down vote up
@NonNull
public Label buildExpectedLabel(IntFunction<Val<Integer>> numViolationsPerLine, int idx) {
    Label foo = new Label();
    foo.getStyleClass().addAll("num-violations-gutter-label");
    Val<Integer> num = numViolationsPerLine.apply(idx + 1);
    foo.textProperty().bind(num.map(Object::toString));
    foo.setTooltip(new Tooltip("Number of violations expected on this line"));
    foo.visibleProperty().bind(num.map(it -> it > 0));
    return foo;
}
 
Example #18
Source File: ControlUtil.java    From pmd-designer with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * When the [boundProp] is blank, display instead the [defaultText]
 * as grayed.
 */
public static void bindLabelPropertyWithDefault(Label label, String defaultText, Val<String> boundProp) {
    Val<String> filteredContent = boundProp.filter(StringUtils::isNotBlank);
    label.textProperty().bind(filteredContent.orElseConst(defaultText));

    filteredContent.values().subscribe(it -> label.pseudoClassStateChanged(PseudoClass.getPseudoClass("default-message"),
                                                                           it == null));

}
 
Example #19
Source File: LineNumberGutterFactory.java    From markdown-writer-fx with BSD 2-Clause "Simplified" License 5 votes vote down vote up
@Override
public Node apply(int paragraphIndex) {
	int lineNo = paragraphIndex + 1;
	Val<String> text = lineCount.map(n -> {
		int digits = Math.max(3, (int) Math.floor(Math.log10(textArea.getParagraphs().size())) + 1);
		return String.format("%" + digits + "d", lineNo);
	});

	Label label = new Label();
	label.textProperty().bind(text.conditionOnShowing(label));
	label.setAlignment(Pos.TOP_RIGHT);
	label.setMaxHeight(Double.MAX_VALUE);
	label.getStyleClass().add("lineno");
	return label;
}
 
Example #20
Source File: NodeEditionCodeArea.java    From pmd-designer with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * TODO does this need to be disableable? Maybe some keyboards use the CTRL key in ways I don't
 */
private void enableCtrlSelection() {

    final Val<Boolean> isNodeSelectionMode =
        ReactfxUtil.vetoableYes(getDesignerRoot().isCtrlDownProperty(), CTRL_SELECTION_VETO_PERIOD);

    addEventHandler(
        MouseOverTextEvent.MOUSE_OVER_TEXT_BEGIN,
        ev -> {
            if (!isNodeSelectionMode.getValue()) {
                return;
            }
            Node currentRoot = getService(DesignerRoot.AST_MANAGER).compilationUnitProperty().getValue();
            if (currentRoot == null) {
                return;
            }

            TextPos2D target = getPmdLineAndColumnFromOffset(this, ev.getCharacterIndex());

            findNodeAt(currentRoot, target)
                .map(n -> NodeSelectionEvent.of(n, new DataHolder().withData(CARET_POSITION, target)))
                .ifPresent(selectionEvts::push);
        }
    );


    isNodeSelectionMode.values().distinct().subscribe(isSelectionMode -> {
        pseudoClassStateChanged(PseudoClass.getPseudoClass("is-node-selection"), isSelectionMode);
        setMouseOverTextDelay(isSelectionMode ? NODE_SELECTION_HOVER_DELAY : null);
    });
}
 
Example #21
Source File: PropertyCollectionView.java    From pmd-designer with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * Makes the property popover for a rule.
 */
public static PopOver makePopOver(ObservableXPathRuleBuilder rule, Val<String> titleProperty, DesignerRoot designerRoot) {
    PropertyCollectionView view = new PropertyCollectionView(designerRoot);

    view.setItems(rule.getRuleProperties());

    PopOver popOver = new SmartPopover(view);
    popOver.titleProperty().bind(titleProperty.map(it -> "Properties of " + it));
    popOver.setHeaderAlwaysVisible(true);
    popOver.setPrefWidth(150);
    popOver.setUserData(view);

    return popOver;
}
 
Example #22
Source File: UndoUtils.java    From RichTextFX with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * Constructs an UndoManager with no history
 */
public static UndoManager noOpUndoManager() {
    return new UndoManager() {

        private final Val<Boolean> alwaysFalse = Val.constant(false);

        @Override public boolean undo() { return false; }
        @Override public boolean redo() { return false; }
        @Override public Val<Boolean> undoAvailableProperty() { return alwaysFalse; }
        @Override public boolean isUndoAvailable() { return false; }
        @Override public Val<Boolean> redoAvailableProperty() { return alwaysFalse; }
        @Override public boolean isRedoAvailable() { return false; }
        @Override public boolean isPerformingAction() { return false; }
        @Override public boolean isAtMarkedPosition() { return false; }

        // not sure whether these may throw NPEs at some point
        @Override public Val nextUndoProperty() { return null; }
        @Override public Val nextRedoProperty() { return null; }
        @Override public ObservableBooleanValue performingActionProperty() { return null; }
        @Override public UndoPosition getCurrentPosition() { return null; }
        @Override public ObservableBooleanValue atMarkedPositionProperty() { return null; }

        // ignore these
        @Override public void preventMerge() { }
        @Override public void forgetHistory() { }
        @Override public void close() { }
    };
}
 
Example #23
Source File: SyntaxHighlightingCodeArea.java    From pmd-designer with BSD 2-Clause "Simplified" License 5 votes vote down vote up
public SyntaxHighlightingCodeArea() {
    // captured in the closure
    final EventHandler<WindowEvent> autoCloseHandler = e -> syntaxAutoRefresh.ifPresent(Subscription::unsubscribe);

    // handles auto shutdown of executor services
    // by attaching a handler to the stage responsible for the control
    Val.wrap(sceneProperty())
       .filter(Objects::nonNull)
       .flatMap(Scene::windowProperty)
       .values()
       .filter(Objects::nonNull)
        .subscribe(c -> c.addEventHandler(WindowEvent.WINDOW_CLOSE_REQUEST, autoCloseHandler));


    // prevent ALT from focusing menu
    addEventFilter(KeyEvent.KEY_PRESSED, e -> {
        if (e.isAltDown()) {
            e.consume();
        }
    });


    // Make TAB 4 spaces
    InputMap<KeyEvent> im = InputMap.consume(
        EventPattern.keyPressed(KeyCode.TAB),
        e -> replaceSelection("    ")
    );

    Nodes.addInputMap(this, im);
}
 
Example #24
Source File: ControlUtil.java    From pmd-designer with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * By default text fields don't show the prompt when the caret is
 * inside the field, even if the text is empty.
 */
public static void makeTextFieldShowPromptEvenIfFocused(TextField field) {
    // See css

    Val.wrap(field.textProperty())
       .values()
       .withDefaultEvent(field.getText())
        .subscribe(text -> field.pseudoClassStateChanged(PseudoClass.getPseudoClass("empty-input"), StringUtils.isBlank(text)));

}
 
Example #25
Source File: MutableTabPane.java    From pmd-designer with BSD 2-Clause "Simplified" License 5 votes vote down vote up
private void initAddButton() {

        Val.wrap(tabPane.skinProperty())
            .values()
            .filter(Objects::nonNull)
            .subscribeForOne(skin -> Platform.runLater(this::makeAddButton));

    }
 
Example #26
Source File: VirtualizedScrollPane.java    From Flowless with BSD 2-Clause "Simplified" License 4 votes vote down vote up
@Override
public Val<Double> totalHeightEstimateProperty() {
    return content.totalHeightEstimateProperty();
}
 
Example #27
Source File: LiveList.java    From ReactFX with BSD 2-Clause "Simplified" License 4 votes vote down vote up
static <E> Val<E> reduce(
        ObservableList<E> list, BinaryOperator<E> reduction) {
    return new ListReduction<>(list, reduction);
}
 
Example #28
Source File: UndoManagerImpl.java    From UndoFX with BSD 2-Clause "Simplified" License 4 votes vote down vote up
@Override
public Val<C> nextRedoProperty() {
    return nextRedo;
}
 
Example #29
Source File: UndoManagerImpl.java    From UndoFX with BSD 2-Clause "Simplified" License 4 votes vote down vote up
@Override
public Val<Boolean> redoAvailableProperty() {
    return nextRedo.map(c -> true).orElseConst(false);
}
 
Example #30
Source File: OrientationHelper.java    From Flowless with BSD 2-Clause "Simplified" License 4 votes vote down vote up
@Override
public Val<Double> widthEstimateProperty(
        VirtualFlow<?, ?> content) {
    return content.totalBreadthEstimateProperty();
}