4

JEditorPane.scrollToReference()動的に生成されたHTMLページでどのように使用されるのか理解できません。選択したアンカーにスクロールされるJEditorPaneでダイアログボックスを開きたいのですが。問題にどのようにアプローチしても、ビューは常にページの下部でスクロールされます。

醜い回避策として、私は現在、HTMLドキュメント全体を解析してアンカータグを探し、それらのオフセットをに保存してから、次のMap<String, Integer>ように呼び出します。

editorPane.setCaretPosition(anchorMap.get("anchor-name"));

...表示されている長方形内のカレットの位置は一見予測不可能であり、ウィンドウの上部にあることはめったにないため、魅力的な結果は得られません。アンカーテキストが表示領域の上部に表示される、よりブラウザのような動作を探しています。

以下は、スクロールバーに触れずに、厄介な回避策(「ヘッダー6」にアンカーがあります)で何が起こるかのスクリーンショットです。

スクリーンショット

何かが足りないと思いますが、正確にはわかりません。

私の現在の回避策のソース:

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();
    }
}
4

1 に答える 1

4

問題は、実行時にペインがまだ表示されていないか、レイアウトされていないscrollToReferenceため、サイズを特定できないことが原因である可能性があります。

の実装にscrollToReferenceは次のブロックがあります。

Rectangle r = modelToView(iter.getStartOffset());
if (r != null) {
   ...
   scrollRectToVisible(r);
}

投稿された例では、ビューがまだ表示されていないか、サイズが正ではないため、長方形はnullの用です。anchor6

スクロールを遅らせるためにこの汚い修正を試してください:

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        editor.scrollToReference("anchor6");
    }
});
JOptionPane.showMessageDialog(new JPanel(), scroller, "",
        JOptionPane.PLAIN_MESSAGE);
于 2012-08-15T21:16:31.883 に答える