All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.fxmisc.richtext.demo.PopupDemo Maven / Gradle / Ivy


package org.fxmisc.richtext.demo;

import javafx.application.Application;
import javafx.geometry.Bounds;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Popup;
import javafx.stage.Stage;

import org.fxmisc.flowless.VirtualizedScrollPane;
import org.fxmisc.richtext.InlineCssTextArea;
import org.reactfx.EventStream;
import org.reactfx.EventStreams;
import org.reactfx.Subscription;
import org.reactfx.value.Var;

import java.util.Optional;

import static org.reactfx.EventStreams.nonNullValuesOf;

/**
 * 

Name: PopupDemo

*

Description: . *

*

Comment: ... *

*

Copyright: Copyright (c) 2016-2019

*

Company: >StA-Soft<

* @author StA * @version 1.0 */ public class PopupDemo extends Application { /** * Stage. */ private Stage stage; /** * Helper class: Popup that can track when it should temporarily hide itself if its object is outside of the * viewport and provides convenience to adding content to both caret/selection popup. */ private class BoundsPopup extends Popup { /** * Indicates whether popup should still be shown even when its item (caret/selection) is outside viewport. */ private final Var showWhenItemOutsideViewport = Var.newSimpleVar(true); /** * Outside. * @return EventStream */ public final EventStream outsideViewportValues() { return showWhenItemOutsideViewport.values(); } /** * Invert. */ public final void invertViewportOption() { showWhenItemOutsideViewport.setValue(!showWhenItemOutsideViewport.getValue()); } /** * Indicates whether popup has been hidden since its item (caret/selection) is outside viewport * and should be shown when that item becomes visible again. */ private final Var hideTemporarily = Var.newSimpleVar(false); /** * Check if it is hidden. * @return true: hidden */ public final boolean isHiddenTemporarily() { return hideTemporarily.getValue(); } /** * Hide. * @param value true: hide */ public final void setHideTemporarily(boolean value) { hideTemporarily.setValue(value); } /** * Invert visibility. */ public final void invertVisibility() { if (isShowing()) { hide(); } else { show(stage); } } /** * V-Box. */ private final VBox vbox; /** * Button. */ private final Button button; /** * Label. */ private final Label label; /** * Set text. * @param text text */ public final void setText(String text) { label.setText(text); } /** * Constructor. * @param buttonText Text */ BoundsPopup(String buttonText) { super(); button = new Button(buttonText); label = new Label(); vbox = new VBox(button, label); vbox.setBackground(new Background(new BackgroundFill(Color.ALICEBLUE, null, null))); vbox.setPadding(new Insets(5)); getContent().add(vbox); } } /** * Create popup options. * @param p bounds popup * @param showHideButtonText text for hide button * @param toggleViewportText text for viewport * @return V-Box */ private VBox createPopupOptions(BoundsPopup p, String showHideButtonText, String toggleViewportText) { Button showOrHidePopup = new Button(showHideButtonText); showOrHidePopup.setOnAction(ae -> p.invertVisibility()); Button toggleOutOfViewportOption = new Button(toggleViewportText); toggleOutOfViewportOption.setOnAction(ae -> p.invertViewportOption()); return new VBox(showOrHidePopup, toggleOutOfViewportOption); } /** * Was auch immer. * @param boundsStream bounds stream * @param popup bounds popup * @param item text * @return was auch immer */ private Subscription feedVisibilityToLabelText(EventStream> boundsStream, BoundsPopup popup, String item) { return boundsStream .map(o -> o.isPresent() ? " is " : " is not ") .subscribe(visibilityStatus -> popup.setText(item + visibilityStatus + "within the viewport")); } @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 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> caretBounds = nonNullValuesOf(area.caretBoundsProperty()); Subscription cBoundsSub = feedVisibilityToLabelText(caretBounds, caretPopup, "Caret"); EventStream> 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 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 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(); } /** * Main-Methode. * @param args Kommandozeilenparameter */ public static void main(String[] args) { launch(args); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy