Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, 2024, Oracle and/or its affiliates.
* Copyright (c) 2023, 2025, Oracle and/or its affiliates.
* All rights reserved. Use is subject to license terms.
*
* This file is available and licensed under the following license:
Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, 2024, Oracle and/or its affiliates.
* Copyright (c) 2023, 2025, Oracle and/or its affiliates.
* All rights reserved. Use is subject to license terms.
*
* This file is available and licensed under the following license:
Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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 = RichUtils.getLineEnding(lineEnding);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
import com.sun.javafx.scene.text.TextFlowHelper;
import com.sun.javafx.scene.text.TextLayout;
import com.sun.javafx.scene.text.TextLine;
import jfx.incubator.scene.control.richtext.LineEnding;
import jfx.incubator.scene.control.richtext.RichTextArea;
import jfx.incubator.scene.control.richtext.TextPos;
import jfx.incubator.scene.control.richtext.model.StyleAttributeMap;
Expand Down Expand Up @@ -167,6 +168,17 @@ public static boolean isTouchSupported() {
return Platform.isSupported(ConditionalFeature.INPUT_TOUCH);
}

public static String getLineEnding(LineEnding v) {
if(v == null) {
return System.getProperty("line.separator");
}
return switch(v) {
case CR -> "\r";
case CRLF -> "\r\n";
case LF -> "\n";
};
}

public static int getTextLength(TextFlow f) {
int len = 0;
for (Node n : f.getChildrenUnmodifiable()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.WritableValue;
import javafx.css.CssMetaData;
import javafx.css.FontCssMetaData;
Expand Down Expand Up @@ -86,6 +87,7 @@
* @since 24
*/
public class CodeArea extends RichTextArea {
private SimpleObjectProperty<LineEnding> lineEnding;
private BooleanProperty lineNumbers;
private StyleableIntegerProperty tabSize;
private StyleableObjectProperty<Font> font;
Expand Down Expand Up @@ -115,6 +117,9 @@ protected void validateModel(StyledTextModel m) {
if ((m != null) && (!(m instanceof CodeTextModel))) {
throw new IllegalArgumentException("CodeArea accepts models that extend CodeTextModel");
}
if (m != null) {
m.setLineEnding(getLineEnding());
}
}

@Override
Expand Down Expand Up @@ -425,8 +430,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) {
Expand All @@ -449,4 +453,41 @@ public final void setText(String text) {
private CodeTextModel codeModel() {
return (CodeTextModel)getModel();
}

/**
* Specifies the line ending characters.
* A {@code null} value results in the platform line ending as reported by
* the {@code line.separator} system property.
* <p>
* Modifying this property causes corresponding update in the underlying model, if the latter is not {@code null}.
*
* @return the line ending property
* @since 26
* @defaultValue null
*/
public final ObjectProperty<LineEnding> lineEndingProperty() {
if (lineEnding == null) {
lineEnding = new SimpleObjectProperty<>(this, "lineEnding") {
@Override
protected void invalidated() {
StyledTextModel m = getModel();
if (m != null) {
m.setLineEnding(get());
}
}
};
}
return lineEnding;
}

public final LineEnding getLineEnding() {
if (lineEnding == null) {
return null;
}
return lineEnding.get();
}

public final void setLineEnding(LineEnding v) {
lineEndingProperty().set(v);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* 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 {
/** Classic Mac OS */
CR,
/** Windows */
CRLF,
/** macOS/Unix */
LF
}
Original file line number Diff line number Diff line change
Expand Up @@ -1451,9 +1451,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 = RichUtils.getLineEnding(m.getLineEnding());
int toCopy = limit;
int index = start.index();
boolean first = true;
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -27,9 +27,10 @@

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 com.sun.jfx.incubator.scene.control.richtext.util.RichUtils;
import jfx.incubator.scene.control.richtext.StyleResolver;
import jfx.incubator.scene.control.richtext.TextPos;

Expand Down Expand Up @@ -61,15 +62,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 = RichUtils.getLineEnding(m.getLineEnding()).getBytes(StandardCharsets.UTF_8);

StyledOutput so = new StyledOutput() {
@Override
Expand All @@ -80,7 +80,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;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -55,6 +56,16 @@ public interface StyledOutput extends Closeable {
* @return the instance of a plain text StyledOutput
*/
public static StyledOutput forPlainText() {
return new StringBuilderStyledOutput();
return new StringBuilderStyledOutput(null);
}

/**
* 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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import com.sun.jfx.incubator.scene.control.richtext.StyleAttributeMapHelper;
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;
Expand Down Expand Up @@ -284,6 +285,7 @@ private record FHKey(DataFormat format, boolean forExport) { }
// TODO should it hold WeakReferences?
private final CopyOnWriteArrayList<Listener> listeners = new CopyOnWriteArrayList();
private final HashMap<FHKey,FHPriority> handlers = new HashMap<>(2);
private LineEnding lineEnding;
private final Markers markers = new Markers();
private final UndoableChange head = UndoableChange.createHead();
private final ReadOnlyBooleanWrapper undoable = new ReadOnlyBooleanWrapper(this, "undoable", false);
Expand Down Expand Up @@ -1007,4 +1009,26 @@ private void checkWritable() {
throw new UnsupportedOperationException("the model is not writeable");
}
}

/**
* Specifies the line ending characters.
* A {@code null} value results in the platform line ending as reported by
* the {@code line.separator} system property.
*
* @return the line ending value
* @defaultValue null
* @since 26
*/
public final LineEnding getLineEnding() {
return lineEnding;
}

/**
* Sets the line ending characters.
* @param value the line ending value, can be null
* @since 26
*/
public final void setLineEnding(LineEnding value) {
lineEnding = value;
}
}
Loading