@@ -45,8 +45,10 @@ public ObjectProperty<Paint> highlightTextFillProperty() {
45
45
46
46
private final Path caretShape = new Path ();
47
47
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 ;
50
52
51
53
// proxy for caretShape.visibleProperty() that implements unbind() correctly.
52
54
// This is necessary due to a bug in BooleanPropertyBase#unbind().
@@ -67,8 +69,8 @@ public ObjectProperty<Paint> highlightTextFillProperty() {
67
69
68
70
selection .addListener ((obs , old , sel ) -> requestLayout ());
69
71
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 );
72
74
73
75
// selection highlight
74
76
selectionShape .setManaged (false );
@@ -95,30 +97,20 @@ public ObjectProperty<Paint> highlightTextFillProperty() {
95
97
// text.impl_selectionFillProperty().set(newFill);
96
98
// }
97
99
// });
100
+ int size = par .getSegments ().size ();
101
+ backgroundShapes = new ArrayList <>(size );
102
+ underlineShapes = new ArrayList <>(size );
98
103
99
104
// populate with text nodes
100
105
for (SEG segment : par .getSegments ()) {
101
106
// create Segment
102
107
Node fxNode = nodeFactory .apply (segment );
103
108
getChildren ().add (fxNode );
104
109
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 );
113
113
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 );
122
114
}
123
115
}
124
116
@@ -221,6 +213,20 @@ private void updateBackgroundShapes() {
221
213
}
222
214
}
223
215
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
+ }
224
230
225
231
/**
226
232
* Updates the background shape for a text segment.
@@ -234,7 +240,7 @@ private void updateBackground(TextExt text, int start, int end, int index) {
234
240
// Set fill
235
241
Paint paint = text .backgroundColorProperty ().get ();
236
242
if (paint != null ) {
237
- Path backgroundShape = backgroundShapes . get (index );
243
+ Path backgroundShape = getBackgroundShape (index );
238
244
backgroundShape .setFill (paint );
239
245
240
246
// Set path elements
@@ -243,6 +249,20 @@ private void updateBackground(TextExt text, int start, int end, int index) {
243
249
}
244
250
}
245
251
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
+ }
246
266
247
267
/**
248
268
* Updates the shape which renders the text underline.
@@ -257,7 +277,7 @@ private void updateUnderline(TextExt text, int start, int end, int index) {
257
277
Number underlineWidth = text .underlineWidthProperty ().get ();
258
278
if (underlineWidth != null && underlineWidth .doubleValue () > 0 ) {
259
279
260
- Path underlineShape = underlineShapes . get (index );
280
+ Path underlineShape = getUnderlineShape (index );
261
281
underlineShape .setStrokeWidth (underlineWidth .doubleValue ());
262
282
263
283
// get remaining CSS properties for the underline style
0 commit comments