diff --git a/richtextfx/src/main/java/org/fxmisc/richtext/ParagraphText.java b/richtextfx/src/main/java/org/fxmisc/richtext/ParagraphText.java index ead69125..f6d2148c 100644 --- a/richtextfx/src/main/java/org/fxmisc/richtext/ParagraphText.java +++ b/richtextfx/src/main/java/org/fxmisc/richtext/ParagraphText.java @@ -104,6 +104,7 @@ public ObjectProperty highlightTextFillProperty() { p.layoutYProperty().unbind(); getChildren().remove(p); + resetTextSelection(p); } if (change.wasAdded()) { SelectionPath p = change.getValueAdded(); @@ -139,22 +140,15 @@ public ObjectProperty highlightTextFillProperty() { }; carets.addListener( caretNodeListener ); - // XXX: see the note at highlightTextFill -// highlightTextFill.addListener(new ChangeListener() { -// @Override -// public void changed(ObservableValue observable, -// Paint oldFill, Paint newFill) { -// for(PumpedUpText text: textNodes()) -// text.selectionFillProperty().set(newFill); -// } -// }); + highlightTextFill.addListener((ob,oldFill,newFill) -> getChildren().stream() + .filter( n -> n instanceof TextExt).map( n -> (TextExt) n ) + .forEach( t -> t.selectionFillProperty().set(newFill) ) + ); // 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 t.selectionFillProperty().bind(highlightTextFill); } getChildren().add(n); @@ -231,7 +225,7 @@ void dispose() { carets.removeListener( caretNodeListener ); getChildren().stream().filter( n -> n instanceof TextExt ).map( n -> (TextExt) n ) - .forEach( t -> t.selectionFillProperty().unbind() ); + .forEach( t -> t.selectionFillProperty().unbind() ); try { getChildren().clear(); } catch ( Exception EX ) {} @@ -336,6 +330,7 @@ private void updateAllSelectionShapes() { private void updateSingleSelection(SelectionPath path) { path.getElements().setAll(getRangeShapeSafely(path.rangeProperty().getValue())); + updateTextSelection(path); } private PathElement[] getRangeShapeSafely(IndexRange range) { @@ -435,32 +430,39 @@ private PathElement[] createRectangle(double topLeftX, double topLeftY, double b }; } + // XXX: Because of JDK bug https://bugs.openjdk.java.net/browse/JDK-8149134 // this does not work correctly if a paragraph contains more than one segment // and the selection is (also) in the second or later segments. // Visually the text color of the selection may be mix black & white. - private void updateTextSelection() { - int selStart = selection.get().getStart(); - int selEnd = selection.get().getEnd(); + private void updateTextSelection(SelectionPath selection) + { + IndexRange range = selection.rangeProperty().getValue(); + if (range.getLength() == 0) { + resetTextSelection(selection); + return; + } - int start = 0; - FilteredList nodeList = getChildren().filtered(node -> node instanceof TextExt); - for (Node node : nodeList) { - TextExt text = (TextExt) node; - int end = start + text.getText().length(); + int selStart = range.getStart(); + int selEnd = range.getEnd(); + int charSoFar = 0; - int textSelStart = Math.max(start, selStart); - int textSelEnd = Math.min(end, selEnd); - if (textSelEnd > textSelStart) { textSelStart -= start; textSelEnd -= start; } else { textSelStart = textSelEnd = -1; + charSoFar = end; } text.setImpl_selectionStart(textSelStart); text.setImpl_selectionEnd(textSelEnd); start = end; + } + } + else if (node.isManaged()) // custom user nodes + { + charSoFar++; + } } } @@ -511,9 +513,8 @@ public String toString() { @Override protected void layoutChildren() { super.layoutChildren(); - updateCaretShape(); - updateSelectionShape(); - updateTextSelection(); + updateAllCaretShapes(); + updateAllSelectionShapes(); updateBackgroundShapes(); } @@ -543,7 +544,7 @@ private void updateSharedShapeRange(T value, int start, int end, BiFunction ranges.add(Tuples.t(value, new IndexRange(start, end))); if (ranges.isEmpty()) { - addNewValueRange.run();; + addNewValueRange.run(); } else { int lastIndex = ranges.size() - 1; Tuple2 lastShapeValueRange = ranges.get(lastIndex);