diff --git a/richtextfx/src/main/java/org/fxmisc/richtext/ParagraphText.java b/richtextfx/src/main/java/org/fxmisc/richtext/ParagraphText.java index 755b5e364..926b6eaca 100644 --- a/richtextfx/src/main/java/org/fxmisc/richtext/ParagraphText.java +++ b/richtextfx/src/main/java/org/fxmisc/richtext/ParagraphText.java @@ -14,6 +14,7 @@ import java.util.function.Function; import java.util.function.Supplier; import java.util.function.UnaryOperator; +import java.util.stream.Collectors; import org.fxmisc.richtext.model.Paragraph; import org.fxmisc.richtext.model.StyledSegment; @@ -70,7 +71,8 @@ public ObjectProperty highlightTextFillProperty() { return highlightTextFill; } - private final Paragraph paragraph; + private Paragraph paragraph; + private Function, Node> nodeMaker; private final CustomCssShapeHelper backgroundShapeHelper; private final CustomCssShapeHelper borderShapeHelper; @@ -88,7 +90,6 @@ public ObjectProperty highlightTextFillProperty() { private int selectionShapeStartIndex = 0; ParagraphText(Paragraph par, Function, Node> nodeFactory) { - this.paragraph = par; getStyleClass().add("paragraph-text"); @@ -149,17 +150,6 @@ public ObjectProperty highlightTextFillProperty() { // } // }); - // populate with text nodes - par.getStyledSegments().stream().map(nodeFactory).forEach(n -> { - if (n instanceof TextExt) { - TextExt t = (TextExt) n; - // XXX: binding selectionFill to textFill, - // see the note at highlightTextFill - JavaFXCompatibility.Text_selectionFillProperty(t).bind(t.fillProperty()); - } - getChildren().add(n); - }); - // set up custom css shape helpers UnaryOperator configurePath = shape -> { shape.setManaged(false); @@ -218,20 +208,45 @@ public ObjectProperty highlightTextFillProperty() { addToForeground, clearUnusedShapes ); + + // populate with text nodes + nodeMaker = nodeFactory; + setParagraph( par ); } void dispose() { - // this removes listeners (in selections and carets listeners) and avoids memory leaks - selections.removeListener( selectionPathListener ); - carets.removeListener( caretNodeListener ); - selections.clear(); carets.clear(); + selections.clear(); + // this removes listeners (in selections and carets listeners) and avoids memory leaks + selections.removeListener( selectionPathListener ); + carets.removeListener( caretNodeListener ); + setParagraph( null ); } public Paragraph getParagraph() { return paragraph; } + public void setParagraph(Paragraph par) { + getChildren().stream().filter( n -> n instanceof TextExt ).map( n -> (TextExt) n ) + .forEach( t -> JavaFXCompatibility.Text_selectionFillProperty(t).unbind() ); + + getChildren().setAll( selections.values() ); + + if ( par != null ) getChildren().addAll( par.getStyledSegments().stream().map(nodeMaker) + .peek( n -> { + if (n instanceof TextExt) { + TextExt t = (TextExt) n; + // XXX: binding selectionFill to textFill, + // see the note at highlightTextFill + JavaFXCompatibility.Text_selectionFillProperty(t).bind(t.fillProperty()); + } + }).collect( Collectors.toList() ) ); + + getChildren().addAll( carets ); + paragraph = par; + } + public double getCaretOffsetX(T caret) { layout(); // ensure layout, is a no-op if not dirty checkWithinParagraph(caret);