0

私の Swing アプリケーションでは、ユーザーは RTFEditorKit を使用するJTextPaneにスタイル付きテキストを入力します (HTML も可能です)。

次に、これらのスタイル付きメモの多くを、カスタム コンポーネントの特定の座標にレンダリングする必要があります。

ここではView.paintメソッドが役立つと思いますが、使用可能な View オブジェクトを作成できません。

私は次の方法を持っています:

public View createView() throws IOException, BadLocationException {
 RTFEditorKit kit = new RTFEditorKit();
 final Document document = kit.createDefaultDocument();
 kit.read(new ByteArrayInputStream(text.getBytes("UTF-8")), document, 0);
 return kit.getViewFactory().create(document.getDefaultRootElement());
}

これは、次の属性を持つ javax.swing.text.BoxView を返します。

majorAxis = 1
majorSpan = 0
minorSpan = 0
majorReqValid = false
minorReqValid = false
majorRequest = null
minorRequest = null
majorAllocValid = false
majorOffsets = {int[0]@2321}
majorSpans = {int[0]@2322}
minorAllocValid = false
minorOffsets = {int[0]@2323}
minorSpans = {int[0]@2324}
tempRect = {java.awt.Rectangle@2325}"java.awt.Rectangle[x=0,y=0,width=0,height=0]"
children = {javax.swing.text.View[1]@2326}
nchildren = 0
left = 0
right = 0
top = 0
bottom = 0
childAlloc = {java.awt.Rectangle@2327}"java.awt.Rectangle[x=0,y=0,width=0,height=0]"
parent = null
elem = {javax.swing.text.DefaultStyledDocument$SectionElement@2328}"BranchElement(section) 0,35\n"

親 = null および nchildren = 0 であることに注意してください。これは、そこには本当に有用なものがないことを意味します。を呼び出して何かをハックすることはできJTextPane.getUI().paintますが、テキスト ペインを表示する必要があり、これは間違った方法のように感じます。

実際の JTextPane をレンダリングせずに RTF コンテンツを視覚的に表現する方法はありますか?

4

2 に答える 2

1

このコードは機能しますが、理想的とは言えません。それを行うより良い方法はありますか?また、グラフィックスの 0,0 以外の場所にテキストをレンダリングする良い方法は何ですか?

private static void testRtfRender() {
    String s = "{\\rtf1\\ansi\n" +
            "{\\fonttbl\\f0\\fnil Monospaced;\\f1\\fnil Lucida Grande;}\n" +
            "\n" +
            "\\f1\\fs26\\i0\\b0\\cf0 this is a \\b test\\b0\\par\n" +
            "}";

    JTextPane pane = new JTextPane();
    pane.setContentType("text/rtf");
    pane.setText(s);

    final Dimension preferredSize = pane.getUI().getPreferredSize(pane);
    int w = preferredSize.width;
    int h = preferredSize.height;

    pane.setSize(w, h);
    pane.addNotify();
    pane.validate();

    // would be nice to use this box view instead of instantiating a UI
    // however, unless you call setParent() on the view it's useless
    // What should the parent of a root element be?
    //BoxView view = (BoxView) pane.getEditorKit().getViewFactory().create(pane.getStyledDocument().getDefaultRootElement());
    //view.paint(d, new Rectangle(w, h));

    BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
    final Graphics2D d = img.createGraphics();
    d.setClip(0, 0, w, h); // throws a NullPointerException if I leave this out
    pane.getUI().paint(d, pane);
    d.dispose();
    JOptionPane.showMessageDialog(null, new JLabel(new ImageIcon(img)));
}
于 2009-10-04T14:09:46.137 に答える