如何将带有 HTMLDocument 的 JTextPane 中的位置转换为 JTextPane 字符串文本中的位置
How to convert the position in JTextPane with HTMLDocument to position in JTextPane string text
我在 java swing 中有一个应用程序包含 JTextPane
和 HTMLDocument
。假设我将窗格的文本设置为:
<html>
<head>
</head>
<body>
<p style="margin-top: 0">
I have a problem now.
</p>
</body>
</html>
所以我在窗格上看到了文本 "I have a problem now."。
假设我单击了一个窗格,插入符号设置在 'p' 和 'r' 之间 "problem" 字。在这种情况下,如果我在 JTextPane
上调用 getCaretPosition
,它将 return 10(如果我算得好 :))。
现在知道这个位置我想把这个位置转换成上面写的 html 字符串中的位置(如果我算得好的话又是 94 :) )
怎么做?
首先你要明白,在html中你不能保持"caret position"的逻辑。正如 StanislavL 告诉您的那样,这没有意义,因为 Hello
也可以被 <html><body>Hello</body></html>
翻译成 <html> <body>Hello</body> </html>
。在这种情况下,您怎么知道哪个位置对应于什么?
错误是试图将 JTextPane 文本内容与其 HTML 转换进行比较。相反,您应该将 HTML 文档与 DOM 进行比较。所以,首先,你需要一个像 JSoup.
这样的 html 解析器
将 JSoup 添加到您的项目后,您可以非常轻松地使 html 和 JTextPane 内容平行。
你可以用这个方法得到html:
public static String getHTMLContent(HTMLDocument htmlDoc, int startOffset, int length) {
StringWriter writer = new StringWriter();
try {
new HTMLEditorKit().write(writer, htmlDoc, startOffset, length);
} catch (IOException | BadLocationException ex) {
Logger.getLogger(Editeur.class.getName()).log(Level.SEVERE, null, ex);
}
String html = writer.toString();
return html;
}
然后你可以用 Jsoup 解析它:
Document doc = Jsoup.parse(html);
doc.getElementById("myId");//get the element by its ID
所以,现在,如果您想在结果 html 中找到 HTML 文档中的特定元素,您需要做的是用 <span>
包围它你会给一个ID,然后用getElementById
得到它。为此,您可以使用 HTMLEditorKit.insertHTML
:
(new HTMLEditorKit()).insertHTML(htmlDoc, pos, "<span id='myId'>element of interest</span>", 0, 0, Tag.SPAN);
例如,要获取所选文本的位置,您可以这样做:
if (getSelectedText() != null && getSelectedText().length()>0) {
try {
String selectedText = getSelectedText()
htmlDoc.remove(getSelectionStart(), this.getSelectedText().length());
(new HTMLEditorKit()).insertHTML(htmlDoc, pos, "<span id='myId'>"+selectedText+"</span>", 0, 0, Tag.SPAN);
} catch (BadLocationException ex) {
Logger.getLogger(Editeur.class.getName()).log(Level.SEVERE, null, ex);
}
}
现在您可以轻松地从 Jsoup 中获取您感兴趣的部分或使用 getElementById
,或者通过 Java 中的 HTMLDocument.getElement(id)
。
如果需要,我可以提供更多关于具体点的详细信息。
我在 java swing 中有一个应用程序包含 JTextPane
和 HTMLDocument
。假设我将窗格的文本设置为:
<html>
<head>
</head>
<body>
<p style="margin-top: 0">
I have a problem now.
</p>
</body>
</html>
所以我在窗格上看到了文本 "I have a problem now."。
假设我单击了一个窗格,插入符号设置在 'p' 和 'r' 之间 "problem" 字。在这种情况下,如果我在 JTextPane
上调用 getCaretPosition
,它将 return 10(如果我算得好 :))。
现在知道这个位置我想把这个位置转换成上面写的 html 字符串中的位置(如果我算得好的话又是 94 :) ) 怎么做?
首先你要明白,在html中你不能保持"caret position"的逻辑。正如 StanislavL 告诉您的那样,这没有意义,因为 Hello
也可以被 <html><body>Hello</body></html>
翻译成 <html> <body>Hello</body> </html>
。在这种情况下,您怎么知道哪个位置对应于什么?
错误是试图将 JTextPane 文本内容与其 HTML 转换进行比较。相反,您应该将 HTML 文档与 DOM 进行比较。所以,首先,你需要一个像 JSoup.
这样的 html 解析器将 JSoup 添加到您的项目后,您可以非常轻松地使 html 和 JTextPane 内容平行。
你可以用这个方法得到html:
public static String getHTMLContent(HTMLDocument htmlDoc, int startOffset, int length) {
StringWriter writer = new StringWriter();
try {
new HTMLEditorKit().write(writer, htmlDoc, startOffset, length);
} catch (IOException | BadLocationException ex) {
Logger.getLogger(Editeur.class.getName()).log(Level.SEVERE, null, ex);
}
String html = writer.toString();
return html;
}
然后你可以用 Jsoup 解析它:
Document doc = Jsoup.parse(html);
doc.getElementById("myId");//get the element by its ID
所以,现在,如果您想在结果 html 中找到 HTML 文档中的特定元素,您需要做的是用 <span>
包围它你会给一个ID,然后用getElementById
得到它。为此,您可以使用 HTMLEditorKit.insertHTML
:
(new HTMLEditorKit()).insertHTML(htmlDoc, pos, "<span id='myId'>element of interest</span>", 0, 0, Tag.SPAN);
例如,要获取所选文本的位置,您可以这样做:
if (getSelectedText() != null && getSelectedText().length()>0) {
try {
String selectedText = getSelectedText()
htmlDoc.remove(getSelectionStart(), this.getSelectedText().length());
(new HTMLEditorKit()).insertHTML(htmlDoc, pos, "<span id='myId'>"+selectedText+"</span>", 0, 0, Tag.SPAN);
} catch (BadLocationException ex) {
Logger.getLogger(Editeur.class.getName()).log(Level.SEVERE, null, ex);
}
}
现在您可以轻松地从 Jsoup 中获取您感兴趣的部分或使用 getElementById
,或者通过 Java 中的 HTMLDocument.getElement(id)
。
如果需要,我可以提供更多关于具体点的详细信息。