我無法弄清楚JEditorPane.scrollToReference()
是如何用於動態生成的HTML頁面的。我想打開一個JEditorPane對話框,滾動到我選擇的錨點。無論我如何解決問題,視圖總是在頁面底部滾動。帶動態生成HTML的JEditorPane.scrollToReference()
作爲一個醜陋的解決辦法,我現在解析爲錨標籤的完整的HTML文檔,保存他們的偏移量在Map<String, Integer>
,然後我打電話:
editorPane.setCaretPosition(anchorMap.get("anchor-name"));
...這甚至不產生吸引力結果,因爲可見矩形內的插入符號位置看起來不可預知,並且很少位於窗口頂部。我正在尋找更類似於瀏覽器的行爲,其中錨定文本出現在可見區域的頂部。
下面是什麼我尷尬的解決方法發生截圖(上有「頭6」錨),而不必觸及滾動條:
screenshot http://i49.tinypic.com/jkaj9s.png
我想我失去了一些東西但我無法弄清楚究竟是什麼。
我目前的解決方法來源:
import javax.swing.*;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.*;
import javax.swing.text.html.HTMLEditorKit.*;
import javax.swing.text.html.parser.*;
import java.io.*;
import java.awt.*;
import java.util.HashMap;
public class AnchorTest
{
public static void main(String[] args)
{
final String html = generateLongPage();
final HashMap<String, Integer> anchors = anchorPositions(html);
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
JEditorPane editor = new JEditorPane("text/html", html);
JScrollPane scroller= new JScrollPane(editor);
scroller.setPreferredSize(new Dimension(400, 250));
//editor.scrollToReference("anchor6"); // doesn't work...
editor.setCaretPosition(anchors.get("anchor6")); //sorta works
JOptionPane.showMessageDialog(new JPanel(), scroller, "",
JOptionPane.PLAIN_MESSAGE);
}});
}
public static HashMap<String, Integer> anchorPositions(String html)
{
final HashMap<String, Integer> map = new HashMap<String, Integer>();
Reader reader = new StringReader(html);
HTMLEditorKit.Parser parser = new ParserDelegator();
try
{
ParserCallback cb = new ParserCallback()
{
public void handleStartTag(HTML.Tag t,
MutableAttributeSet a,
int pos)
{
if (t == HTML.Tag.A) {
String name =
(String)a.getAttribute(HTML.Attribute.NAME);
map.put(name, pos);
}
}
};
parser.parse(reader, cb, true);
}
catch (IOException ignore) {}
return map;
}
public static String generateLongPage()
{
StringBuilder sb = new StringBuilder(
"<html><head><title>hello</title></head><body>\n");
for (int i = 0; i < 10; i++) {
sb.append(String.format(
"<h1><a name='anchor%d'>header %d</a></h1>\n<p>", i, i));
for (int j = 0; j < 100; j++) {
sb.append("blah ");
}
sb.append("</p>\n\n");
}
return sb.append("</body></html>").toString();
}
}
我有同樣的想法,你,但它並沒有區別,當我嘗試過。你有不同的結果嗎? – 2012-08-15 21:41:14
@NickRippe是的,它滾動確定。 – tenorsax 2012-08-15 21:43:01
啊,是的 - 現在我可以開始工作。 'showMessageDialog'和'scrollToReference'都需要位於'invokeLater'語句中(按此順序)。我一定有一些東西被弄糊塗了。 +1 – 2012-08-15 21:57:08