Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package org.fxmisc.richtext.demo;

import java.time.Duration;
import java.util.Collection;
import java.util.Collections;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

Expand All @@ -20,13 +17,9 @@

import org.fxmisc.flowless.VirtualizedScrollPane;
import org.fxmisc.richtext.CodeArea;
import org.fxmisc.richtext.GenericStyledArea;
import org.fxmisc.richtext.LineNumberFactory;
import org.fxmisc.richtext.model.Paragraph;
import org.fxmisc.richtext.model.StyleSpans;
import org.fxmisc.richtext.model.StyleSpansBuilder;
import org.reactfx.collection.ListModification;
import org.reactfx.Subscription;

public class JavaKeywordsDemo extends Application {

Expand Down Expand Up @@ -120,10 +113,7 @@ public void start(Stage primaryStage) {
// recompute syntax highlighting only for visible paragraph changes
// Note that this shows how it can be done but is not recommended for production where multi-
// line syntax requirements are needed, like comment blocks without a leading * on each line.
codeArea.getVisibleParagraphs().addModificationObserver
(
new VisibleParagraphStyler<>( codeArea, this::computeHighlighting )
);
codeArea.setVisibleOnlyStyler( p -> p.restyle( 0, computeHighlighting( p.getText() ) ) );

// auto-indent: insert previous line's indents on enter
final Pattern whiteSpace = Pattern.compile( "^\\s+" );
Expand Down Expand Up @@ -170,40 +160,6 @@ private StyleSpans<Collection<String>> computeHighlighting(String text) {
return spansBuilder.create();
}

private class VisibleParagraphStyler<PS, SEG, S> implements Consumer<ListModification<? extends Paragraph<PS, SEG, S>>>
{
private final GenericStyledArea<PS, SEG, S> area;
private final Function<String,StyleSpans<S>> computeStyles;
private int prevParagraph, prevTextLength;

public VisibleParagraphStyler( GenericStyledArea<PS, SEG, S> area, Function<String,StyleSpans<S>> computeStyles )
{
this.computeStyles = computeStyles;
this.area = area;
}

@Override
public void accept( ListModification<? extends Paragraph<PS, SEG, S>> lm )
{
if ( lm.getAddedSize() > 0 ) Platform.runLater( () ->
{
int paragraph = Math.min( area.firstVisibleParToAllParIndex() + lm.getFrom(), area.getParagraphs().size()-1 );
String text = area.getText( paragraph, 0, paragraph, area.getParagraphLength( paragraph ) );

if ( paragraph != prevParagraph || text.length() != prevTextLength )
{
if ( paragraph < area.getParagraphs().size()-1 )
{
int startPos = area.getAbsolutePosition( paragraph, 0 );
area.setStyleSpans( startPos, computeStyles.apply( text ) );
}
prevTextLength = text.length();
prevParagraph = paragraph;
}
});
}
}

private class DefaultContextMenu extends ContextMenu
{
private MenuItem fold, unfold, print;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1548,6 +1548,20 @@ public final PS getParagraphStyleForInsertionAt(int pos) {
}
}

private UnaryOperator<Paragraph<PS, SEG, S>> visibleOnlyStyler;
/**
* This styler will only be applied to Paragraphs, just before being displayed.
* <p><b>Important Notes</b></p>
* <ol>
* <li> The result of this styling does NOT modify the document model.
* <li> Paragraph is immutable, so don't return the same object expecting changes.
* <li> The styler should return the result of one of Paragraph's restyle methods.
* </ol>
*/
public void setVisibleOnlyStyler(UnaryOperator<Paragraph<PS, SEG, S>> styler) {
visibleOnlyStyler = styler;
}

@Override
public void replaceText(int start, int end, String text) {
StyledDocument<PS, SEG, S> doc = ReadOnlyStyledDocument.fromString(
Expand Down Expand Up @@ -1914,6 +1928,7 @@ private Cell<Paragraph<PS, SEG, S>, ParagraphBox<PS, SEG, S>> createCell(
BiConsumer<TextFlow, PS> applyParagraphStyle,
Function<StyledSegment<SEG, S>, Node> nodeFactory) {

if (visibleOnlyStyler != null) paragraph = visibleOnlyStyler.apply(paragraph);
ParagraphBox<PS, SEG, S> box = new ParagraphBox<>(paragraph, applyParagraphStyle, nodeFactory);

box.highlightTextFillProperty().bind(highlightTextFill);
Expand Down