Skip to content

Commit a4e4142

Browse files
author
Andy Goryachev
committed
8370253: CodeArea: NPE on copy
Reviewed-by: kcr
1 parent 42fd4eb commit a4e4142

File tree

3 files changed

+73
-21
lines changed

3 files changed

+73
-21
lines changed

modules/jfx.incubator.richtext/src/main/java/com/sun/jfx/incubator/scene/control/richtext/RtfStyledOutput.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -517,8 +517,13 @@ public void close() throws IOException {
517517
}
518518

519519
private static Color getTextColor(StyleAttributeMap a) {
520-
Color c = a.getTextColor();
521-
return c == null ? Color.BLACK : c;
520+
if (a != null) {
521+
Color c = a.getTextColor();
522+
if (c != null) {
523+
return c;
524+
}
525+
}
526+
return Color.BLACK;
522527
}
523528

524529
/** RTF is unable to specify colors inline it seems, needs a color lookup table */

modules/jfx.incubator.richtext/src/main/java/jfx/incubator/scene/control/richtext/model/RichParagraph.java

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -155,24 +155,6 @@ void export(int start, int end, StyledOutput out) throws IOException {
155155
}
156156
}
157157

158-
// for use by SimpleReadOnlyStyledModel
159-
StyleAttributeMap getStyleAttributeMap(StyleResolver resolver, int offset) {
160-
int off = 0;
161-
List<StyledSegment> segments = getSegments();
162-
if (segments != null) {
163-
int sz = segments.size();
164-
for (int i = 0; i < sz; i++) {
165-
StyledSegment seg = segments.get(i);
166-
int len = seg.getTextLength();
167-
if (offset < (off + len) || (i == sz - 1)) {
168-
return seg.getStyleAttributeMap(resolver);
169-
}
170-
off += len;
171-
}
172-
}
173-
return StyleAttributeMap.EMPTY;
174-
}
175-
176158
private static void initAccessor() {
177159
RichParagraphHelper.setAccessor(new RichParagraphHelper.Accessor() {
178160
@Override

modules/jfx.incubator.richtext/src/test/java/test/jfx/incubator/scene/control/richtext/CodeAreaTest.java

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,27 @@
3030
import static org.junit.jupiter.api.Assertions.assertThrows;
3131
import static org.junit.jupiter.api.Assertions.assertTrue;
3232
import java.util.List;
33+
import java.util.Set;
3334
import javafx.css.CssMetaData;
3435
import javafx.css.Styleable;
3536
import javafx.scene.Scene;
37+
import javafx.scene.input.Clipboard;
38+
import javafx.scene.input.DataFormat;
39+
import javafx.scene.paint.Color;
3640
import javafx.scene.text.Font;
3741
import org.junit.jupiter.api.AfterEach;
3842
import org.junit.jupiter.api.BeforeEach;
3943
import org.junit.jupiter.api.Test;
4044
import jfx.incubator.scene.control.richtext.CodeArea;
4145
import jfx.incubator.scene.control.richtext.RichTextArea;
46+
import jfx.incubator.scene.control.richtext.SyntaxDecorator;
47+
import jfx.incubator.scene.control.richtext.TextPos;
4248
import jfx.incubator.scene.control.richtext.model.CodeTextModel;
49+
import jfx.incubator.scene.control.richtext.model.RichParagraph;
4350
import jfx.incubator.scene.control.richtext.model.RichTextModel;
51+
import jfx.incubator.scene.control.richtext.model.StyleAttributeMap;
4452
import jfx.incubator.scene.control.richtext.skin.CodeAreaSkin;
53+
import test.jfx.incubator.scene.control.richtext.support.RTUtil;
4554
import test.jfx.incubator.scene.util.TUtil;
4655

4756
/**
@@ -143,6 +152,62 @@ public void testPropertyBinding() {
143152

144153
// functional API tests
145154

155+
@Test
156+
public void copy() {
157+
RTUtil.copyToClipboard("yo");
158+
control.appendText("123");
159+
control.selectAll();
160+
control.copy();
161+
assertEquals("123", Clipboard.getSystemClipboard().getString());
162+
163+
control.select(TextPos.ZERO, TextPos.ofLeading(0, 1));
164+
control.copy();
165+
assertEquals("1", Clipboard.getSystemClipboard().getString());
166+
167+
control.select(TextPos.ofLeading(0, 1), TextPos.ofLeading(0, 2));
168+
control.copy();
169+
assertEquals("2", Clipboard.getSystemClipboard().getString());
170+
171+
control.select(TextPos.ofLeading(0, 2), TextPos.ofLeading(0, 3));
172+
control.copy();
173+
assertEquals("3", Clipboard.getSystemClipboard().getString());
174+
175+
control.appendText("\n4");
176+
control.select(new TextPos(0, 3, 2, false), control.getDocumentEnd());
177+
control.copy();
178+
String nl = System.getProperty("line.separator");
179+
assertEquals(nl + "4", Clipboard.getSystemClipboard().getString());
180+
}
181+
182+
@Test
183+
public void copyWithSyntaxDecorator() {
184+
control.appendText("123");
185+
control.setSyntaxDecorator(new SyntaxDecorator() {
186+
private static final StyleAttributeMap DIGITS = StyleAttributeMap.builder().setTextColor(Color.MAGENTA).build();
187+
188+
@Override
189+
public RichParagraph createRichParagraph(CodeTextModel model, int index) {
190+
String text = model.getPlainText(index);
191+
RichParagraph.Builder b = RichParagraph.builder();
192+
int len = text.length();
193+
b.addSegment(text, 0, 1, null);
194+
b.addSegment(text, 1, 2, DIGITS);
195+
b.addSegment(text, 2, len, null);
196+
return b.build();
197+
}
198+
199+
@Override
200+
public void handleChange(CodeTextModel m, TextPos start, TextPos end, int charsTop, int linesAdded, int charsBottom) {
201+
}
202+
});
203+
control.select(TextPos.ZERO);
204+
control.selectParagraph();
205+
control.copy();
206+
Clipboard cb = Clipboard.getSystemClipboard();
207+
assertEquals("123", cb.getString());
208+
assertEquals(Set.of(DataFormat.PLAIN_TEXT, DataFormat.HTML, DataFormat.RTF), cb.getContentTypes());
209+
}
210+
146211
@Test
147212
public void getControlCssMetaData() {
148213
List<CssMetaData<? extends Styleable, ?>> md = control.getControlCssMetaData();

0 commit comments

Comments
 (0)