Skip to content

Commit c8bdf5a

Browse files
Cleanup demos to use multiPlainChanges instead of plainChanges()
1 parent e9029be commit c8bdf5a

3 files changed

Lines changed: 33 additions & 10 deletions

File tree

richtextfx-demos/src/main/java/org/fxmisc/richtext/demo/JavaKeywords.java

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.fxmisc.richtext.demo;
22

3+
import java.time.Duration;
34
import java.util.Collection;
45
import java.util.Collections;
56
import java.util.regex.Matcher;
@@ -15,6 +16,7 @@
1516
import org.fxmisc.richtext.LineNumberFactory;
1617
import org.fxmisc.richtext.model.StyleSpans;
1718
import org.fxmisc.richtext.model.StyleSpansBuilder;
19+
import org.reactfx.Subscription;
1820

1921
public class JavaKeywords extends Application {
2022

@@ -80,13 +82,27 @@ public static void main(String[] args) {
8082
@Override
8183
public void start(Stage primaryStage) {
8284
CodeArea codeArea = new CodeArea();
85+
86+
// add line numbers to the left of area
8387
codeArea.setParagraphGraphicFactory(LineNumberFactory.get(codeArea));
8488

85-
codeArea.richChanges()
86-
.filter(ch -> !ch.getInserted().equals(ch.getRemoved())) // XXX
87-
.subscribe(change -> {
88-
codeArea.setStyleSpans(0, computeHighlighting(codeArea.getText()));
89-
});
89+
// recompute the syntax highlighting 500 ms after user stops editing area
90+
Subscription cleanupWhenNoLongerNeedIt = codeArea
91+
92+
// plain changes = ignore style changes that are emitted when syntax highlighting is reapplied
93+
// multi plain changes = save computation by not rerunning the code multiple times
94+
// when making multiple changes (e.g. renaming a method at multiple parts in file)
95+
.multiPlainChanges()
96+
97+
// do not emit an event until 500 ms have passed since the last emission of previous stream
98+
.successionEnds(Duration.ofMillis(500))
99+
100+
// run the following code block when previous stream emits an event
101+
.subscribe(ignore -> codeArea.setStyleSpans(0, computeHighlighting(codeArea.getText())));
102+
103+
// when no longer need syntax highlighting and wish to clean up memory leaks
104+
// run: `cleanupWhenNoLongerNeedIt.unsubscribe();`
105+
90106
codeArea.replaceText(0, 0, sampleCode);
91107

92108
Scene scene = new Scene(new StackPane(new VirtualizedScrollPane<>(codeArea)), 600, 400);

richtextfx-demos/src/main/java/org/fxmisc/richtext/demo/JavaKeywordsAsync.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.fxmisc.richtext.LineNumberFactory;
2121
import org.fxmisc.richtext.model.StyleSpans;
2222
import org.fxmisc.richtext.model.StyleSpansBuilder;
23+
import org.reactfx.Subscription;
2324

2425
public class JavaKeywordsAsync extends Application {
2526

@@ -90,11 +91,10 @@ public void start(Stage primaryStage) {
9091
executor = Executors.newSingleThreadExecutor();
9192
codeArea = new CodeArea();
9293
codeArea.setParagraphGraphicFactory(LineNumberFactory.get(codeArea));
93-
codeArea.richChanges()
94-
.filter(ch -> !ch.getInserted().equals(ch.getRemoved())) // XXX
94+
Subscription cleanupWhenDone = codeArea.multiPlainChanges()
9595
.successionEnds(Duration.ofMillis(500))
9696
.supplyTask(this::computeHighlightingAsync)
97-
.awaitLatest(codeArea.richChanges())
97+
.awaitLatest(codeArea.multiPlainChanges())
9898
.filterMap(t -> {
9999
if(t.isSuccess()) {
100100
return Optional.of(t.get());
@@ -104,6 +104,9 @@ public void start(Stage primaryStage) {
104104
}
105105
})
106106
.subscribe(this::applyHighlighting);
107+
108+
// call when no longer need it: `cleanupWhenFinished.unsubscribe();`
109+
107110
codeArea.replaceText(0, 0, sampleCode);
108111

109112
Scene scene = new Scene(new StackPane(new VirtualizedScrollPane<>(codeArea)), 600, 400);

richtextfx-demos/src/main/java/org/fxmisc/richtext/demo/SpellChecking.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.io.InputStream;
66
import java.io.InputStreamReader;
77
import java.text.BreakIterator;
8+
import java.time.Duration;
89
import java.util.Collection;
910
import java.util.Collections;
1011
import java.util.HashSet;
@@ -19,6 +20,7 @@
1920
import javafx.scene.Scene;
2021
import javafx.scene.layout.StackPane;
2122
import javafx.stage.Stage;
23+
import org.reactfx.Subscription;
2224

2325
public class SpellChecking extends Application {
2426

@@ -33,12 +35,14 @@ public void start(Stage primaryStage) {
3335
StyleClassedTextArea textArea = new StyleClassedTextArea();
3436
textArea.setWrapText(true);
3537

36-
textArea.richChanges()
37-
.filter(ch -> !ch.getInserted().equals(ch.getRemoved())) // XXX
38+
Subscription cleanupWhenFinished = textArea.multiPlainChanges()
39+
.successionEnds(Duration.ofMillis(500))
3840
.subscribe(change -> {
3941
textArea.setStyleSpans(0, computeHighlighting(textArea.getText()));
4042
});
4143

44+
// call when no longer need it: `cleanupWhenFinished.unsubscribe();`
45+
4246
// load the dictionary
4347
try (InputStream input = getClass().getResourceAsStream("spellchecking.dict");
4448
BufferedReader br = new BufferedReader(new InputStreamReader(input))) {

0 commit comments

Comments
 (0)