TextArea Swing 和 JavaFX select 范围差异
TextArea Swing and JavaFX select range difference
目前我正在编写一个 Swing 应用程序来显示 JTextArea
中的源代码(C++,Java,...),包括 select ing 文本查看器中的元素。对于select,使用元素的位置偏移和内容长度。这是我的代码:
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格式):
/*---------------Arithmetic operator---------------*/
int PlusTest(int x, int y){
int z = x + y;
if (z > 0)
return 1;
else
return 0;
}
注意: 示例代码开头有2个空行
这段代码运行良好,它 selectC++ 函数声明部分的范围:
现在,我在 JavaFX 8(Java 版本:1.8.0_112)中编写了一个类似的应用程序:
package application;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.layout.VBox;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
VBox root = new VBox();
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)"));
Button btn1 = new Button("Select function (JavaFX)");
TextArea area1 = new TextArea(content);
root.getChildren().addAll(btn1, area1);
btn1.setOnAction(e->{
area1.selectRange(functionOffset, functionOffset + functionLength);
});
Scene scene = new Scene(root,800, 300);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
这是结果:
那么,为什么这里会有差异?我使用了错误的功能吗?
感谢您的帮助
编辑 1
试试这个代码:
System.out.println(content.length());
System.out.println(area1.getText().length());
结果是:JavaFX 版本
中的 157 146
在 Swing 版本中,它是:157 157
似乎 TextArea
忽略回车 return ("\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;
}
有趣的分支是 if (c < 0x20) return true;
,这意味着回车 return 字符被标记为无效,因此它不会附加到控件的文本中
由于您的文件使用CR+LF作为行分隔符,如果您执行以下操作:
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
因此,在将字符串添加到 TextArea
之前从字符串中删除 CR 字符应该可以解决问题:
String content = new String(Files.readAllBytes(Paths.get("src/application/File.cpp")), Charset.forName("UTF-8"));
content = content.replaceAll("\r\n", "\n");
目前我正在编写一个 Swing 应用程序来显示 JTextArea
中的源代码(C++,Java,...),包括 select ing 文本查看器中的元素。对于select,使用元素的位置偏移和内容长度。这是我的代码:
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格式):
/*---------------Arithmetic operator---------------*/
int PlusTest(int x, int y){
int z = x + y;
if (z > 0)
return 1;
else
return 0;
}
注意: 示例代码开头有2个空行
这段代码运行良好,它 selectC++ 函数声明部分的范围:
现在,我在 JavaFX 8(Java 版本:1.8.0_112)中编写了一个类似的应用程序:
package application;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.layout.VBox;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
VBox root = new VBox();
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)"));
Button btn1 = new Button("Select function (JavaFX)");
TextArea area1 = new TextArea(content);
root.getChildren().addAll(btn1, area1);
btn1.setOnAction(e->{
area1.selectRange(functionOffset, functionOffset + functionLength);
});
Scene scene = new Scene(root,800, 300);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
这是结果:
那么,为什么这里会有差异?我使用了错误的功能吗? 感谢您的帮助
编辑 1
试试这个代码:
System.out.println(content.length());
System.out.println(area1.getText().length());
结果是:JavaFX 版本
中的 157 146
在 Swing 版本中,它是:157 157
似乎 TextArea
忽略回车 return ("\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;
}
有趣的分支是 if (c < 0x20) return true;
,这意味着回车 return 字符被标记为无效,因此它不会附加到控件的文本中
由于您的文件使用CR+LF作为行分隔符,如果您执行以下操作:
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
因此,在将字符串添加到 TextArea
之前从字符串中删除 CR 字符应该可以解决问题:
String content = new String(Files.readAllBytes(Paths.get("src/application/File.cpp")), Charset.forName("UTF-8"));
content = content.replaceAll("\r\n", "\n");