TextArea Swing和JavaFX选择范围差异

TextArea Swing和JavaFX选择范围差异,java,swing,javafx,textarea,javafx-8,Java,Swing,Javafx,Textarea,Javafx 8,目前我正在编写一个Swing应用程序来显示JTextArea中的源代码(C++,Java,…),包括在文本查看器中选择元素。要进行选择,请使用元素的位置偏移和内容长度。这是我的代码: package application; import java.awt.BorderLayout; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; import javax.swi

目前我正在编写一个Swing应用程序来显示
JTextArea
中的源代码(C++,Java,…),包括在文本查看器中选择元素。要进行选择,请使用元素的位置偏移和内容长度。这是我的代码:

package application;

import java.awt.BorderLayout;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;

public class MainSwing {

    public static void main(String[] args) throws Exception{
        JFrame frame = new JFrame();
        frame.setSize(500, 400);
        String content = new String(Files.readAllBytes(Paths.get("src/application/File.cpp")), Charset.forName("UTF-8"));
        int functionOffset = 61;
        int functionLength = 26;
        System.out.println(content.indexOf("int PlusTest(int x, int y)"));

        JPanel panel = new JPanel(new BorderLayout());

        JButton btn = new JButton("Select function (Swing)");
        panel.add(btn, BorderLayout.NORTH);

        JTextArea area = new JTextArea(content);
        panel.add(area, BorderLayout.CENTER);

        btn.addActionListener(e-> {
            area.requestFocusInWindow();
            area.setCaretPosition(functionOffset);
            area.moveCaretPosition(functionOffset + functionLength);
        });

        frame.setContentPane(panel);
        frame.setVisible(true);
    }

}
示例源文件(另存为ANSI、CR-LF格式):

注意:示例代码开头有两行空行
该代码运行良好,它选择了C++函数声明的范围:



现在,我用JavaFX8(Java版本:1.8.0112)编写了一个类似的应用程序:

这就是结果:

那么,为什么这里有区别呢?我是否使用了错误的函数? 谢谢你的帮助


编辑1
请尝试以下代码:

System.out.println(content.length());
System.out.println(area1.getText().length());
结果是:157146在JavaFX版本中

在Swing版本中,它是:157

似乎
TextArea
忽略回车(“\r”)并使用换行符(“\n”)作为行分隔符

要测试它,请执行以下操作:

TextArea area1 = new TextArea("\r\n");
System.out.println((int) "\r\n".charAt(0));
System.out.println((int) "\r\n".charAt(1));

System.out.println("TextArea text length: " + area1.getText().length());

System.out.println((int) area1.getText().charAt(0));
以及输出:

13
10
TextArea text length: 1
10

更新:

挖掘
TextInputControl
的源代码可以得到这部分代码:

private static boolean isInvalidCharacter(char c, boolean newlineIllegal, boolean tabIllegal) {
    if (c == 0x7F) return true;
    if (c == 0xA) return newlineIllegal;
    if (c == 0x9) return tabIllegal;
    if (c < 0x20) return true;
    return false;
}
输出为:

Offset before: 61 and after: 57
因此,在将字符串添加到
TextArea
之前从字符串中删除CR字符应该可以解决以下问题:

String content = new String(Files.readAllBytes(Paths.get("src/application/File.cpp")), Charset.forName("UTF-8"));
content = content.replaceAll("\r\n", "\n");

这并不是对您的问题的真正回答,但您为什么不使用类似于
area1.getText().indexOf(“int-PlusTest(int-x,int-y)”)
的方法来获取函数的正确偏移量呢?这将返回索引55,它似乎是函数的正确起始位置。我真正的应用程序以C/C++源代码作为输入,使用第三方插件(EclipseCDT)解析其中的所有令牌元素及其位置。之后,我使用这个位置在源代码查看器中选择范围。如果我的源代码包含2个不同的2个C++函数,那么方法就不起作用了。class@DVarga,问题是在JavaFX版本中,它应该像在Swing版本中一样选择“intplustest(intx,inty)”,但它确实选择了not@DVarga,@Jonatan Stenbacka:我试过
System.out.println(content.indexOf(“intplustest(intx,inty)”)
在两个版本和两个打印61中都作为起始位置是的,很可能
“\r\n”(CR+LF)
将变得简单
\n
,这就是差异的来源<代码>内容=内容.replaceAll(“\r\n”,“\n”)似乎解决了问题。
int functionOffset = content.indexOf("int PlusTest(int x, int y)");
content = content.replaceAll("\r\n", "\n");
int functionOffset2 = content.indexOf("int PlusTest(int x, int y)");

System.out.println("Offset before: " + functionOffset + " and after: " + functionOffset2);
Offset before: 61 and after: 57
String content = new String(Files.readAllBytes(Paths.get("src/application/File.cpp")), Charset.forName("UTF-8"));
content = content.replaceAll("\r\n", "\n");