将 RTF/HTML 字符串绘制到自定义 swing 组件中

发布于 2024-08-06 09:15:48 字数 1686 浏览 4 评论 0原文

在我的 Swing 应用程序中,用户将样式文本输入 JTextPane 它使用 RTFEditorKit(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"

请注意,parent = null 和 nchildren = 0。这意味着那里没有任何真正有用的东西。我可以通过调用 JTextPane.getUI().paint 来组合一些东西,但是文本窗格需要可见,这感觉像是错误的方法。

有没有什么方法可以在不渲染实际 JTextPane 的情况下获得 RTF 内容的可视化表示?

In my Swing application, users enter styled text into a JTextPane which uses an RTFEditorKit (HTML is also a possibility).

I then need to render many of these styled notes at specific coordinates in a custom component.

I would think the View.paint method would be helpful here, but I'm not able to create a usable View object.

I have the following method:

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

This returns a javax.swing.text.BoxView with the following attributes:

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"

Note that parent = null and nchildren = 0. This means there's nothing really useful there. I can hack together something by calling JTextPane.getUI().paint, but the text pane needs to be visible, and this feels like the wrong way to do it.

Is there any way to get a visual representation of the RTF content without rendering the actual JTextPane?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

迷乱花海 2024-08-13 09:15:48

这段代码可以工作,但似乎不太理想。有更好的方法吗?另外,在图形上除 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)));
}

This code sort of works, but seems less than ideal. Is there a better way to do it? Also, what's a good way to render the text somewhere other than 0,0 on the graphics?

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)));
}
混吃等死 2024-08-13 09:15:48

查看 ScreenImage 类,它允许您创建 BufferedImage任何 Swing 组件的。它也应该适用于不可见的 Swing 组件,但是您必须首先进行渲染。

Check out the ScreenImage class which allows you to create a BufferedImage of any Swing component. It should also work for Swing components that are not visible, but yes you do have to do the rendering first.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文