diff --git a/richtextfx/src/main/java/org/fxmisc/richtext/GenericStyledArea.java b/richtextfx/src/main/java/org/fxmisc/richtext/GenericStyledArea.java index d7c8b0908..10ca6db07 100644 --- a/richtextfx/src/main/java/org/fxmisc/richtext/GenericStyledArea.java +++ b/richtextfx/src/main/java/org/fxmisc/richtext/GenericStyledArea.java @@ -1190,7 +1190,7 @@ public int getCurrentLineEndInParargraph() { } private double caretPrevY = -1; - private Selection lineHighlighter; + private LineSelection lineHighlighter; private ObjectProperty lineHighlighterFill; /** @@ -1228,34 +1228,13 @@ public void setLineHighlighterOn( boolean show ) { if ( lineHighlighter != null ) return; - lineHighlighter = new SelectionImpl<>( "line-highlighter", this, path -> - { - if ( lineHighlighterFill == null ) path.setHighlightFill( Color.YELLOW ); - else path.highlightFillProperty().bind( lineHighlighterFill ); - - path.getElements().addListener( (Change chg) -> - { - if ( chg.next() && chg.wasAdded() || chg.wasReplaced() ) { - double width = path.getParent().getLayoutBounds().getWidth(); - // The path is limited to the bounds of the text, so here it's altered to the area's width - chg.getAddedSubList().stream().skip(1).limit(2).forEach( ele -> ((LineTo) ele).setX( width ) ); - // The path can wrap onto another line if enough text is inserted, so here it's trimmed - if ( chg.getAddedSize() > 5 ) path.getElements().remove( 5, 10 ); - // Highlight masks the downward selection of text on the last line, so move it behind - path.toBack(); - } - } ); - } ); + lineHighlighter = new LineSelection<>( this, lineHighlighterFill ); Runnable adjustHighlighterRange = () -> { if ( lineHighlighter != null ) { - int p = getCurrentParagraph(); - int start = getCurrentLineStartInParargraph(); - int end = getCurrentLineEndInParargraph(); - if (end == 0) end++;// +1 for empty lines - lineHighlighter.selectRange( p, start, p, end ); + lineHighlighter.selectCurrentLine(); } }; @@ -1677,8 +1656,8 @@ private Cell, ParagraphBox> createCell( if (p == null) { // create & configure path Val range = Val.create( - () -> boxIndex != -1 - ? getParagraphSelection(selection, boxIndex) + () -> box.getIndex() != -1 + ? getParagraphSelection(selection, box.getIndex()) : EMPTY_RANGE, selection.rangeProperty() ); diff --git a/richtextfx/src/main/java/org/fxmisc/richtext/LineSelection.java b/richtextfx/src/main/java/org/fxmisc/richtext/LineSelection.java new file mode 100644 index 000000000..8660a5c48 --- /dev/null +++ b/richtextfx/src/main/java/org/fxmisc/richtext/LineSelection.java @@ -0,0 +1,47 @@ +package org.fxmisc.richtext; + +import javafx.beans.property.ObjectProperty; +import javafx.collections.ListChangeListener.Change; +import javafx.scene.paint.Color; +import javafx.scene.paint.Paint; +import javafx.scene.shape.LineTo; +import javafx.scene.shape.PathElement; + +class LineSelection extends SelectionImpl +{ + LineSelection( GenericStyledArea area, ObjectProperty lineHighlighterFill ) + { + super( "line-highlighter", area, path -> + { + if ( lineHighlighterFill == null ) path.setHighlightFill( Color.YELLOW ); + else path.highlightFillProperty().bind( lineHighlighterFill ); + + path.getElements().addListener( (Change chg) -> + { + if ( chg.next() && chg.wasAdded() || chg.wasReplaced() ) { + double width = path.getParent().getLayoutBounds().getWidth(); + // The path is limited to the bounds of the text, so here it's altered to the area's width + chg.getAddedSubList().stream().skip(1).limit(2).forEach( ele -> ((LineTo) ele).setX( width ) ); + // The path can wrap onto another line if enough text is inserted, so here it's trimmed + if ( chg.getAddedSize() > 5 ) path.getElements().remove( 5, 10 ); + // Highlight masks the downward selection of text on the last line, so move it behind + path.toBack(); + } + } ); + } ); + } + + @Override + public void selectRange( int start, int end ) + { + selectCurrentLine(); + } + + public void selectCurrentLine() + { + int p = getArea().getCurrentParagraph(); + int start = getArea().getAbsolutePosition( p, getArea().getCurrentLineStartInParargraph() ); + int end = getArea().getAbsolutePosition( p, getArea().getCurrentLineEndInParargraph() ); + super.selectRange( start, (end > start) ? end : start+1 ); // +1 for empty lines + } +}