Skip to content

Commit

Permalink
Improved syntax highlighting demo (#956)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jugen committed Aug 27, 2020
1 parent 8838871 commit bb39321
Showing 1 changed file with 45 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
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 @@ -16,9 +18,11 @@

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.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 @@ -88,8 +92,8 @@ public void start(Stage primaryStage) {

// add line numbers to the left of area
codeArea.setParagraphGraphicFactory(LineNumberFactory.get(codeArea));

// recompute the syntax highlighting 500 ms after user stops editing area
/*
// recompute the syntax highlighting for all text, 500 ms after user stops editing area
Subscription cleanupWhenNoLongerNeedIt = codeArea
// plain changes = ignore style changes that are emitted when syntax highlighting is reapplied
Expand All @@ -105,7 +109,12 @@ public void start(Stage primaryStage) {
// when no longer need syntax highlighting and wish to clean up memory leaks
// run: `cleanupWhenNoLongerNeedIt.unsubscribe();`

*/
// recompute syntax highlighting only for visible paragraph changes
codeArea.getVisibleParagraphs().addModificationObserver
(
new VisibleParagraphStyler<>( codeArea, this::computeHighlighting )
);

// auto-indent: insert previous line's indents on enter
final Pattern whiteSpace = Pattern.compile( "^\\s+" );
Expand All @@ -129,7 +138,7 @@ public void start(Stage primaryStage) {
primaryStage.show();
}

private static StyleSpans<Collection<String>> computeHighlighting(String text) {
private StyleSpans<Collection<String>> computeHighlighting(String text) {
Matcher matcher = PATTERN.matcher(text);
int lastKwEnd = 0;
StyleSpansBuilder<Collection<String>> spansBuilder
Expand All @@ -151,4 +160,36 @@ private static StyleSpans<Collection<String>> computeHighlighting(String text) {
spansBuilder.add(Collections.emptyList(), text.length() - lastKwEnd);
return spansBuilder.create();
}

private class VisibleParagraphStyler<PS, SEG, S> implements Consumer<ListModification>
{
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 lm )
{
if ( lm.getAddedSize() > 0 )
{
int paragraph = area.visibleParToAllParIndex( lm.getFrom() );
String text = area.getText( paragraph, 0, paragraph, area.getParagraphLength( paragraph ) );

if ( paragraph != prevParagraph || text.length() != prevTextLength )
{
int startPos = area.getAbsolutePosition( paragraph, 0 );
Platform.runLater( () -> area.setStyleSpans( startPos, computeStyles.apply( text ) ) );
prevTextLength = text.length();
prevParagraph = paragraph;
}
}
}
}

}

0 comments on commit bb39321

Please sign in to comment.