Skip to content

Commit 542786c

Browse files
Merge pull request #557 from JordanMartinez/optimizeShapes
Only construct background/underline shapes when needed
2 parents 164273c + d6141c6 commit 542786c

File tree

1 file changed

+42
-22
lines changed

1 file changed

+42
-22
lines changed

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

+42-22
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,10 @@ public ObjectProperty<Paint> highlightTextFillProperty() {
4545

4646
private final Path caretShape = new Path();
4747
private final Path selectionShape = new Path();
48-
private final List<Path> backgroundShapes = new ArrayList<>();
49-
private final List<Path> underlineShapes = new ArrayList<>();
48+
private final List<Path> backgroundShapes;
49+
private final List<Path> underlineShapes;
50+
private final Val<Double> leftInset;
51+
private final Val<Double> topInset;
5052

5153
// proxy for caretShape.visibleProperty() that implements unbind() correctly.
5254
// This is necessary due to a bug in BooleanPropertyBase#unbind().
@@ -67,8 +69,8 @@ public ObjectProperty<Paint> highlightTextFillProperty() {
6769

6870
selection.addListener((obs, old, sel) -> requestLayout());
6971

70-
Val<Double> leftInset = Val.map(insetsProperty(), Insets::getLeft);
71-
Val<Double> topInset = Val.map(insetsProperty(), Insets::getTop);
72+
leftInset = Val.map(insetsProperty(), Insets::getLeft);
73+
topInset = Val.map(insetsProperty(), Insets::getTop);
7274

7375
// selection highlight
7476
selectionShape.setManaged(false);
@@ -95,30 +97,20 @@ public ObjectProperty<Paint> highlightTextFillProperty() {
9597
// text.impl_selectionFillProperty().set(newFill);
9698
// }
9799
// });
100+
int size = par.getSegments().size();
101+
backgroundShapes = new ArrayList<>(size);
102+
underlineShapes = new ArrayList<>(size);
98103

99104
// populate with text nodes
100105
for(SEG segment: par.getSegments()) {
101106
// create Segment
102107
Node fxNode = nodeFactory.apply(segment);
103108
getChildren().add(fxNode);
104109

105-
// add corresponding background node (empty)
106-
Path backgroundShape = new Path();
107-
backgroundShape.setManaged(false);
108-
backgroundShape.setStrokeWidth(0);
109-
backgroundShape.layoutXProperty().bind(leftInset);
110-
backgroundShape.layoutYProperty().bind(topInset);
111-
backgroundShapes.add(backgroundShape);
112-
getChildren().add(0, backgroundShape);
110+
// add placeholder to prevent IOOBE; only create shapes when needed
111+
backgroundShapes.add(null);
112+
underlineShapes.add(null);
113113

114-
// add corresponding underline node (empty)
115-
Path underlineShape = new Path();
116-
underlineShape.setManaged(false);
117-
underlineShape.setStrokeWidth(0);
118-
underlineShape.layoutXProperty().bind(leftInset);
119-
underlineShape.layoutYProperty().bind(topInset);
120-
underlineShapes.add(underlineShape);
121-
getChildren().add(underlineShape);
122114
}
123115
}
124116

@@ -221,6 +213,20 @@ private void updateBackgroundShapes() {
221213
}
222214
}
223215

216+
private Path getBackgroundShape(int index) {
217+
Path backgroundShape = backgroundShapes.get(index);
218+
if (backgroundShape == null) {
219+
// add corresponding background node (empty)
220+
backgroundShape = new Path();
221+
backgroundShape.setManaged(false);
222+
backgroundShape.setStrokeWidth(0);
223+
backgroundShape.layoutXProperty().bind(leftInset);
224+
backgroundShape.layoutYProperty().bind(topInset);
225+
backgroundShapes.set(index, backgroundShape);
226+
getChildren().add(0, backgroundShape);
227+
}
228+
return backgroundShape;
229+
}
224230

225231
/**
226232
* Updates the background shape for a text segment.
@@ -234,7 +240,7 @@ private void updateBackground(TextExt text, int start, int end, int index) {
234240
// Set fill
235241
Paint paint = text.backgroundColorProperty().get();
236242
if (paint != null) {
237-
Path backgroundShape = backgroundShapes.get(index);
243+
Path backgroundShape = getBackgroundShape(index);
238244
backgroundShape.setFill(paint);
239245

240246
// Set path elements
@@ -243,6 +249,20 @@ private void updateBackground(TextExt text, int start, int end, int index) {
243249
}
244250
}
245251

252+
private Path getUnderlineShape(int index) {
253+
Path underlineShape = underlineShapes.get(index);
254+
if (underlineShape == null) {
255+
// add corresponding underline node (empty)
256+
underlineShape = new Path();
257+
underlineShape.setManaged(false);
258+
underlineShape.setStrokeWidth(0);
259+
underlineShape.layoutXProperty().bind(leftInset);
260+
underlineShape.layoutYProperty().bind(topInset);
261+
underlineShapes.set(index, underlineShape);
262+
getChildren().add(underlineShape);
263+
}
264+
return underlineShape;
265+
}
246266

247267
/**
248268
* Updates the shape which renders the text underline.
@@ -257,7 +277,7 @@ private void updateUnderline(TextExt text, int start, int end, int index) {
257277
Number underlineWidth = text.underlineWidthProperty().get();
258278
if (underlineWidth != null && underlineWidth.doubleValue() > 0) {
259279

260-
Path underlineShape = underlineShapes.get(index);
280+
Path underlineShape = getUnderlineShape(index);
261281
underlineShape.setStrokeWidth(underlineWidth.doubleValue());
262282

263283
// get remaining CSS properties for the underline style

0 commit comments

Comments
 (0)