diff --git a/apps/samples/RichTextAreaDemo/src/com/oracle/demo/richtext/notebook/CodeCellTextModel.java b/apps/samples/RichTextAreaDemo/src/com/oracle/demo/richtext/notebook/CodeCellTextModel.java index d60e17eddff..7db546e5e11 100644 --- a/apps/samples/RichTextAreaDemo/src/com/oracle/demo/richtext/notebook/CodeCellTextModel.java +++ b/apps/samples/RichTextAreaDemo/src/com/oracle/demo/richtext/notebook/CodeCellTextModel.java @@ -72,7 +72,7 @@ public void setText(String text) { public String getText() { try { - StyledOutput out = StyledOutput.forPlainText(); + StyledOutput out = StyledOutput.forPlainText(getLineEnding()); TextPos end = getDocumentEnd(); export(TextPos.ZERO, end, out); return out.toString(); diff --git a/apps/samples/RichTextAreaDemo/src/com/oracle/demo/richtext/notebook/TextCellTextModel.java b/apps/samples/RichTextAreaDemo/src/com/oracle/demo/richtext/notebook/TextCellTextModel.java index a027d69dcc8..643ec04817e 100644 --- a/apps/samples/RichTextAreaDemo/src/com/oracle/demo/richtext/notebook/TextCellTextModel.java +++ b/apps/samples/RichTextAreaDemo/src/com/oracle/demo/richtext/notebook/TextCellTextModel.java @@ -70,7 +70,7 @@ public void setText(String text) { public String getPlainText() { try { - StyledOutput out = StyledOutput.forPlainText(); + StyledOutput out = StyledOutput.forPlainText(getLineEnding()); TextPos end = getDocumentEnd(); export(TextPos.ZERO, end, out); return out.toString(); diff --git a/modules/jfx.incubator.richtext/src/main/java/com/sun/jfx/incubator/scene/control/richtext/StringBuilderStyledOutput.java b/modules/jfx.incubator.richtext/src/main/java/com/sun/jfx/incubator/scene/control/richtext/StringBuilderStyledOutput.java index 72608ad5435..d8297fe7cf3 100644 --- a/modules/jfx.incubator.richtext/src/main/java/com/sun/jfx/incubator/scene/control/richtext/StringBuilderStyledOutput.java +++ b/modules/jfx.incubator.richtext/src/main/java/com/sun/jfx/incubator/scene/control/richtext/StringBuilderStyledOutput.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,23 +26,18 @@ package com.sun.jfx.incubator.scene.control.richtext; import java.io.IOException; +import com.sun.jfx.incubator.scene.control.richtext.util.RichUtils; +import jfx.incubator.scene.control.richtext.LineEnding; import jfx.incubator.scene.control.richtext.model.StyledOutput; import jfx.incubator.scene.control.richtext.model.StyledSegment; public class StringBuilderStyledOutput implements StyledOutput { private final StringBuilder sb; - private String newline = System.getProperty("line.separator"); + private final String newline; - public StringBuilderStyledOutput(int initialCapacity) { - sb = new StringBuilder(initialCapacity); - } - - public StringBuilderStyledOutput() { - this(1024); - } - - public void setLineSeparator(String s) { - newline = s; + public StringBuilderStyledOutput(LineEnding lineEnding) { + sb = new StringBuilder(1024); + newline = lineEnding.getText(); } @Override diff --git a/modules/jfx.incubator.richtext/src/main/java/jfx/incubator/scene/control/richtext/CodeArea.java b/modules/jfx.incubator.richtext/src/main/java/jfx/incubator/scene/control/richtext/CodeArea.java index fd8f9d87725..04cd3ff1d4a 100644 --- a/modules/jfx.incubator.richtext/src/main/java/jfx/incubator/scene/control/richtext/CodeArea.java +++ b/modules/jfx.incubator.richtext/src/main/java/jfx/incubator/scene/control/richtext/CodeArea.java @@ -425,8 +425,7 @@ public final String getText() { return ""; } TextPos end = m.getDocumentEnd(); - try (StringBuilderStyledOutput out = new StringBuilderStyledOutput()) { - out.setLineSeparator("\n"); + try (StringBuilderStyledOutput out = new StringBuilderStyledOutput(m.getLineEnding())) { m.export(TextPos.ZERO, end, out); return out.toString(); } catch (IOException e) { diff --git a/modules/jfx.incubator.richtext/src/main/java/jfx/incubator/scene/control/richtext/LineEnding.java b/modules/jfx.incubator.richtext/src/main/java/jfx/incubator/scene/control/richtext/LineEnding.java new file mode 100644 index 00000000000..a7e6fa8b9cb --- /dev/null +++ b/modules/jfx.incubator.richtext/src/main/java/jfx/incubator/scene/control/richtext/LineEnding.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jfx.incubator.scene.control.richtext; + +/** + * Specifies line separator (line ending) characters. + * + * @since 26 + */ +public enum LineEnding { + /** Legacy Mac OS line ending, ASCII CR (0x0d). */ + CR, + /** Windows line ending, sequence of CR/LF (0x0d 0x0a). */ + CRLF, + /** macOS/Unix line ending, ASCII LF (0x0a). */ + LF; + + private static final LineEnding system = init(); + + /** + * Returns the line ending as a {@code String}. + * @return the line ending string + */ + public String getText() { + return switch(this) { + case CR -> "\r"; + case CRLF -> "\r\n"; + case LF -> "\n"; + }; + } + + /** + * Returns the system default {@code LineEnding} based on the value of system property + * {@code System.getProperty("line.separator")}. + * @return the system default line ending + */ + public static LineEnding system() { + return system; + } + + private static LineEnding init() { + String s = System.getProperty("line.separator"); + if (s != null) { + return switch (s) { + case "\r" -> CR; + case "\r\n" -> CRLF; + case "\n" -> LF; + default -> LF; + }; + } + return LineEnding.LF; + } +} diff --git a/modules/jfx.incubator.richtext/src/main/java/jfx/incubator/scene/control/richtext/RichTextArea.java b/modules/jfx.incubator.richtext/src/main/java/jfx/incubator/scene/control/richtext/RichTextArea.java index 721ebc1efef..6708bff6c75 100644 --- a/modules/jfx.incubator.richtext/src/main/java/jfx/incubator/scene/control/richtext/RichTextArea.java +++ b/modules/jfx.incubator.richtext/src/main/java/jfx/incubator/scene/control/richtext/RichTextArea.java @@ -619,6 +619,35 @@ public final void setLeftDecorator(SideDecorator d) { leftDecoratorProperty().set(d); } + /** + * Convenience method which delegates to {@link StyledTextModel#getLineEnding()}. + * Returns {@link LineEnding#system()} value if the model is {@code null}. + * + * @return the model's line ending value + * @since 26 + */ + public final LineEnding getLineEnding() { + StyledTextModel m = getModel(); + return (m == null ? LineEnding.system() : m.getLineEnding()); + } + + /** + * Sets the model's line ending characters. + * Delegates to {@link StyledTextModel#setLineEnding(LineEnding)}. + * This method does nothing if the model is {@code null}. + * + * @param value the line ending value, cannot be null + * @throws NullPointerException if the value is null + * @since 26 + */ + public final void setLineEnding(LineEnding value) { + Objects.requireNonNull(value, "line ending must not be null"); + StyledTextModel m = getModel(); + if (m != null) { + m.setLineEnding(value); + } + } + /** * Determines the {@link StyledTextModel} to use with this RichTextArea. * The model can be null, which results in an empty, uneditable control. @@ -1479,9 +1508,7 @@ private final boolean getText(TextPos start, TextPos end, StringBuilder sb, int end = tmp; } - // TODO JDK-8370140 (line separator property) - String lineSeparator = System.getProperty("line.separator"); - + String lineSeparator = m.getLineEnding().getText(); int toCopy = limit; int index = start.index(); boolean first = true; diff --git a/modules/jfx.incubator.richtext/src/main/java/jfx/incubator/scene/control/richtext/model/PlainTextFormatHandler.java b/modules/jfx.incubator.richtext/src/main/java/jfx/incubator/scene/control/richtext/model/PlainTextFormatHandler.java index 3928ee762b9..dc38411a549 100644 --- a/modules/jfx.incubator.richtext/src/main/java/jfx/incubator/scene/control/richtext/model/PlainTextFormatHandler.java +++ b/modules/jfx.incubator.richtext/src/main/java/jfx/incubator/scene/control/richtext/model/PlainTextFormatHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ import java.io.IOException; import java.io.OutputStream; -import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import javafx.scene.input.DataFormat; import com.sun.jfx.incubator.scene.control.richtext.StringBuilderStyledOutput; import jfx.incubator.scene.control.richtext.StyleResolver; @@ -61,15 +61,14 @@ public StyledInput createStyledInput(String text, StyleAttributeMap attr) { @Override public Object copy(StyledTextModel m, StyleResolver resolver, TextPos start, TextPos end) throws IOException { - StringBuilderStyledOutput out = new StringBuilderStyledOutput(); + StringBuilderStyledOutput out = new StringBuilderStyledOutput(m.getLineEnding()); m.export(start, end, out); return out.toString(); } @Override public void save(StyledTextModel m, StyleResolver resolver, TextPos start, TextPos end, OutputStream out) throws IOException { - Charset charset = Charset.forName("utf-8"); - byte[] newline = System.getProperty("line.separator").getBytes(charset); + byte[] newline = m.getLineEnding().getText().getBytes(StandardCharsets.UTF_8); StyledOutput so = new StyledOutput() { @Override @@ -80,7 +79,7 @@ public void consume(StyledSegment seg) throws IOException { break; case TEXT: String text = seg.getText(); - byte[] b = text.getBytes(charset); + byte[] b = text.getBytes(StandardCharsets.UTF_8); out.write(b); break; } diff --git a/modules/jfx.incubator.richtext/src/main/java/jfx/incubator/scene/control/richtext/model/StyledOutput.java b/modules/jfx.incubator.richtext/src/main/java/jfx/incubator/scene/control/richtext/model/StyledOutput.java index 090697b732d..4cb0e89f86a 100644 --- a/modules/jfx.incubator.richtext/src/main/java/jfx/incubator/scene/control/richtext/model/StyledOutput.java +++ b/modules/jfx.incubator.richtext/src/main/java/jfx/incubator/scene/control/richtext/model/StyledOutput.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ import java.io.Closeable; import java.io.IOException; import com.sun.jfx.incubator.scene.control.richtext.StringBuilderStyledOutput; +import jfx.incubator.scene.control.richtext.LineEnding; /** * Class represents a consumer of styled text segments for the purposes of @@ -51,10 +52,20 @@ public interface StyledOutput extends Closeable { public void flush() throws IOException; /** - * Creates an instance of a plain text StyledOutput. + * Creates an instance of a plain text StyledOutput with the platform line ending. * @return the instance of a plain text StyledOutput */ public static StyledOutput forPlainText() { - return new StringBuilderStyledOutput(); + return new StringBuilderStyledOutput(LineEnding.system()); + } + + /** + * Creates an instance of a plain text StyledOutput with the specified line ending characters. + * @param lineEnding the line ending characters + * @return the instance of a plain text StyledOutput + * @since 26 + */ + public static StyledOutput forPlainText(LineEnding lineEnding) { + return new StringBuilderStyledOutput(lineEnding); } } diff --git a/modules/jfx.incubator.richtext/src/main/java/jfx/incubator/scene/control/richtext/model/StyledTextModel.java b/modules/jfx.incubator.richtext/src/main/java/jfx/incubator/scene/control/richtext/model/StyledTextModel.java index f3ac0908280..402f48e9b1d 100644 --- a/modules/jfx.incubator.richtext/src/main/java/jfx/incubator/scene/control/richtext/model/StyledTextModel.java +++ b/modules/jfx.incubator.richtext/src/main/java/jfx/incubator/scene/control/richtext/model/StyledTextModel.java @@ -49,6 +49,7 @@ import com.sun.jfx.incubator.scene.control.richtext.StyledTextModelHelper; import com.sun.jfx.incubator.scene.control.richtext.UndoableChange; import com.sun.jfx.incubator.scene.control.richtext.util.RichUtils; +import jfx.incubator.scene.control.richtext.LineEnding; import jfx.incubator.scene.control.richtext.Marker; import jfx.incubator.scene.control.richtext.StyleResolver; import jfx.incubator.scene.control.richtext.TextPos; @@ -288,6 +289,7 @@ private record FHKey(DataFormat format, boolean forExport) { } // TODO should it hold WeakReferences? private final CopyOnWriteArrayList listeners = new CopyOnWriteArrayList(); private final HashMap handlers = new HashMap<>(2); + private LineEnding lineEnding = LineEnding.system(); private final Markers markers = new Markers(); private final UndoableChange head = UndoableChange.createHead(); private final ReadOnlyBooleanWrapper undoable = new ReadOnlyBooleanWrapper(this, "undoable", false); @@ -1060,4 +1062,26 @@ private void checkWritable() { throw new UnsupportedOperationException("the model is not writeable"); } } + + /** + * Specifies the line ending characters. + * + * @return the line ending value + * @defaultValue {@link LineEnding#system()} + * @since 26 + */ + public final LineEnding getLineEnding() { + return lineEnding; + } + + /** + * Sets the line ending characters. + * @param value the line ending value, cannot be null + * @throws NullPointerException if the value is null + * @since 26 + */ + public final void setLineEnding(LineEnding value) { + Objects.requireNonNull(value, "line ending must not be null"); + lineEnding = value; + } } diff --git a/modules/jfx.incubator.richtext/src/test/java/test/jfx/incubator/scene/control/richtext/CodeAreaTest.java b/modules/jfx.incubator.richtext/src/test/java/test/jfx/incubator/scene/control/richtext/CodeAreaTest.java index 8ceaf43e157..158d3c5f7e3 100644 --- a/modules/jfx.incubator.richtext/src/test/java/test/jfx/incubator/scene/control/richtext/CodeAreaTest.java +++ b/modules/jfx.incubator.richtext/src/test/java/test/jfx/incubator/scene/control/richtext/CodeAreaTest.java @@ -42,6 +42,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import jfx.incubator.scene.control.richtext.CodeArea; +import jfx.incubator.scene.control.richtext.LineEnding; import jfx.incubator.scene.control.richtext.RichTextArea; import jfx.incubator.scene.control.richtext.SyntaxDecorator; import jfx.incubator.scene.control.richtext.TextPos; @@ -219,6 +220,7 @@ public void getControlCssMetaData() { @Test public void getText() { control.setText("123"); + control.setLineEnding(LineEnding.LF); String s = control.getText(); assertEquals("123", s); @@ -263,4 +265,47 @@ public void modelAcceptable() { control.setModel(m); assertTrue(control.getModel() == m); } + + @Test + public void lineEnding() { + control.setText("1\n2\n3"); + assertEquals(3, control.getParagraphCount()); + t(LineEnding.CR, "1\r2\r3"); + t(LineEnding.CRLF, "1\r\n2\r\n3"); + t(LineEnding.LF, "1\n2\n3"); + } + + @Test + public void lineEndingNull() { + assertThrows(NullPointerException.class, () -> { + control.setLineEnding(null); + }); + } + + private void t(LineEnding lineEnding, String expected) { + control.setLineEnding(lineEnding); + assertEquals(lineEnding, control.getLineEnding()); + assertEquals(expected, control.getText()); + control.select(TextPos.ZERO, control.getDocumentEnd()); + control.copy(); + assertEquals(expected, Clipboard.getSystemClipboard().getString()); + } + + @Test + public void setText() { + String expected = "1\n2\n3\n4"; + String[] variants = { + "1\n2\n3\n4", + "1\r2\r3\r4", + "1\r\n2\r\n3\r\n4", + "1\r2\n3\r\n4" + }; + control.setLineEnding(LineEnding.LF); + for (int i = 0; i < variants.length; i++) { + String s = variants[i]; + control.setText(s); + String text = control.getText(); + assertEquals(expected, text, "variant=" + i); + } + } } diff --git a/modules/jfx.incubator.richtext/src/test/java/test/jfx/incubator/scene/control/richtext/RichTextAreaTest.java b/modules/jfx.incubator.richtext/src/test/java/test/jfx/incubator/scene/control/richtext/RichTextAreaTest.java index 35f8b2b87db..473e1f9bcb8 100644 --- a/modules/jfx.incubator.richtext/src/test/java/test/jfx/incubator/scene/control/richtext/RichTextAreaTest.java +++ b/modules/jfx.incubator.richtext/src/test/java/test/jfx/incubator/scene/control/richtext/RichTextAreaTest.java @@ -29,6 +29,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -52,6 +53,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import com.sun.jfx.incubator.scene.control.richtext.VFlow; +import jfx.incubator.scene.control.richtext.LineEnding; import jfx.incubator.scene.control.richtext.RichTextArea; import jfx.incubator.scene.control.richtext.RichTextAreaShim; import jfx.incubator.scene.control.richtext.SelectionSegment; @@ -62,6 +64,7 @@ import jfx.incubator.scene.control.richtext.model.RichTextFormatHandler; import jfx.incubator.scene.control.richtext.model.RichTextModel; import jfx.incubator.scene.control.richtext.model.StyleAttributeMap; +import jfx.incubator.scene.control.richtext.model.StyledTextModel; import jfx.incubator.scene.control.richtext.skin.RichTextAreaSkin; import test.jfx.incubator.scene.control.richtext.support.RTUtil; import test.jfx.incubator.scene.control.richtext.support.TestStyledInput; @@ -357,6 +360,43 @@ public void copy() { assertEquals(NL + "4", Clipboard.getSystemClipboard().getString()); } + @Test + public void lineEndingCopy() { + control.appendText("1\n2\n3"); + assertEquals(3, control.getParagraphCount()); + t(LineEnding.CR, "1\r2\r3"); + t(LineEnding.CRLF, "1\r\n2\r\n3"); + t(LineEnding.LF, "1\n2\n3"); + } + + @Test + public void lineEndingNull() { + assertThrows(NullPointerException.class, () -> { + control.getModel().setLineEnding(null); + }); + } + + @Test + public void lineEndingNullModel() { + control.setModel(null); + assertEquals(LineEnding.system(), control.getLineEnding()); + control.setLineEnding(LineEnding.CR); + assertEquals(LineEnding.system(), control.getLineEnding()); + assertThrows(NullPointerException.class, () -> { + control.setLineEnding(null); + }); + } + + private void t(LineEnding lineEnding, String expected) { + StyledTextModel m = control.getModel(); + m.setLineEnding(lineEnding); + assertEquals(lineEnding, m.getLineEnding()); + assertEquals(expected, text()); + control.select(TextPos.ZERO, control.getDocumentEnd()); + control.copy(); + assertEquals(expected, Clipboard.getSystemClipboard().getString()); + } + @Test public void copyDataFormat() { RTUtil.copyToClipboard(""); diff --git a/modules/jfx.incubator.richtext/src/test/java/test/jfx/incubator/scene/control/richtext/model/TestRichTextModel.java b/modules/jfx.incubator.richtext/src/test/java/test/jfx/incubator/scene/control/richtext/model/TestRichTextModel.java index 92e97ed5559..bf1462ecfdf 100644 --- a/modules/jfx.incubator.richtext/src/test/java/test/jfx/incubator/scene/control/richtext/model/TestRichTextModel.java +++ b/modules/jfx.incubator.richtext/src/test/java/test/jfx/incubator/scene/control/richtext/model/TestRichTextModel.java @@ -26,12 +26,14 @@ package test.jfx.incubator.scene.control.richtext.model; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import com.sun.jfx.incubator.scene.control.richtext.SegmentStyledInput; +import jfx.incubator.scene.control.richtext.LineEnding; import jfx.incubator.scene.control.richtext.TextPos; import jfx.incubator.scene.control.richtext.model.RichParagraph; import jfx.incubator.scene.control.richtext.model.RichTextModel; @@ -40,6 +42,7 @@ import jfx.incubator.scene.control.richtext.model.StyledInput; import jfx.incubator.scene.control.richtext.model.StyledSegment; import jfx.incubator.scene.control.richtext.model.StyledTextModel; +import test.jfx.incubator.scene.control.richtext.support.RTUtil; /** * Tests RichTextModel. @@ -272,4 +275,29 @@ public void clamp() { assertEquals(TextPos.ofLeading(2, 0), m.clamp(TextPos.ofLeading(2, 100))); } + + @Test + public void lineEnding() { + RichTextModel m = createModel("1\n2\n3"); + assertEquals(LineEnding.system(), m.getLineEnding()); + assertEquals(3, m.size()); + m.setLineEnding(LineEnding.CR); + assertEquals(LineEnding.CR, m.getLineEnding()); + assertEquals("1\r2\r3", RTUtil.getText(m)); + m.setLineEnding(LineEnding.CRLF); + assertEquals(LineEnding.CRLF, m.getLineEnding()); + assertEquals("1\r\n2\r\n3", RTUtil.getText(m)); + m.setLineEnding(LineEnding.LF); + assertEquals(LineEnding.LF, m.getLineEnding()); + assertEquals("1\n2\n3", RTUtil.getText(m)); + } + + @Test + public void lineEndingNull() { + RichTextModel m = createModel("1\n2\n3"); + assertThrows(NullPointerException.class, () -> { + m.setLineEnding(null); + }); + assertEquals(LineEnding.system(), m.getLineEnding()); + } } diff --git a/modules/jfx.incubator.richtext/src/test/java/test/jfx/incubator/scene/control/richtext/support/RTUtil.java b/modules/jfx.incubator.richtext/src/test/java/test/jfx/incubator/scene/control/richtext/support/RTUtil.java index 645915b1c65..31d6ae25645 100644 --- a/modules/jfx.incubator.richtext/src/test/java/test/jfx/incubator/scene/control/richtext/support/RTUtil.java +++ b/modules/jfx.incubator.richtext/src/test/java/test/jfx/incubator/scene/control/richtext/support/RTUtil.java @@ -34,6 +34,7 @@ import com.sun.javafx.tk.Toolkit; import jfx.incubator.scene.control.richtext.RichTextArea; import jfx.incubator.scene.control.richtext.TextPos; +import jfx.incubator.scene.control.richtext.model.StyledTextModel; /** * Utilities for RichTextArea-based tests. @@ -61,10 +62,26 @@ public static void setText(RichTextArea control, String text) { * @return the plain text */ public static String getText(RichTextArea control) { + try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { + control.write(DataFormat.PLAIN_TEXT, out); + byte[] b = out.toByteArray(); + return new String(b, StandardCharsets.UTF_8); + } catch (IOException e) { + throw new AssertionError(e); + } + } + + /** + * Extracts plain text from the supplied StyledTextModel, using {@code write(DataFormat.PLAIN_TEXT)} method. + * + * @param model the model + * @return the plain text + */ + public static String getText(StyledTextModel model) { ByteArrayOutputStream out = new ByteArrayOutputStream(); try { try { - control.write(DataFormat.PLAIN_TEXT, out); + model.write(null, DataFormat.PLAIN_TEXT, out); byte[] b = out.toByteArray(); return new String(b, StandardCharsets.UTF_8); } finally {