Skip to content

Commit 4e6ce6b

Browse files
Correct the default plainChanges implementation and explain the quirky code.
1 parent 0fea082 commit 4e6ce6b

1 file changed

Lines changed: 32 additions & 3 deletions

File tree

richtextfx/src/main/java/org/fxmisc/richtext/EditableStyledDocument.java

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,39 @@ public interface EditableStyledDocument<PS, S> extends StyledDocument<PS, S> {
2020
ReadOnlyStyledDocument<PS, S> snapshot();
2121

2222
default EventStream<PlainTextChange> plainChanges() {
23+
/*
24+
The following code might seem a bit strange, but here's why it's used:
25+
If a rich change is emitted that only changes the style, then inserted and removed are equal.
26+
So, we want to exclude those style changes and only include changes where the actual text was modified
27+
(e.g. some text was inserted/removed)
28+
29+
If we use the following code, "getText() is repeated twice:
30+
richChanges().filterMap(
31+
// excludes style changes
32+
c -> c.inserted.getText().equals(c.removed.getText()), // first time
33+
c -> new PlainTextChange(c.position, c.removed.getText(), c.inserted.getText() // second time
34+
)
35+
36+
To prevent code repetition, we could map the RichTextChange to a PlainTextChange and then filter out
37+
the PlainTextChanges that don't actually change anything (the RichTextChange was merely a style change)
38+
However, this produces unneeded PlainTextChange objects.
39+
40+
So, to reduce code repetition and use less memory, the following approach is used.
41+
*/
2342
return richChanges()
24-
// only allow changes that added/removed text; exclude style changes
25-
.filter(c -> c.insertedLength() != 0 || c.removedLength() != 0)
26-
.map(c -> new PlainTextChange(c.position, c.removed.getText(), c.inserted.getText()));
43+
.map(c -> {
44+
String inserted = c.inserted.getText();
45+
String removed = c.removed.getText();
46+
if (!inserted.equals(removed)) {
47+
// if reached, the rich change was an actual text change, not a style change...
48+
return new PlainTextChange(c.position, removed, inserted);
49+
} else {
50+
// if reached, the rich change was a style change; text wasn't modified
51+
return null;
52+
}
53+
})
54+
// now filter out the null values (the style changes) to insure no null events are emitted
55+
.filter(c -> c != null);
2756
}
2857

2958
EventStream<RichTextChange<PS, S>> richChanges();

0 commit comments

Comments
 (0)