【问题标题】:Paint RTF/HTML strings into a custom swing component将 RTF/HTML 字符串绘制到自定义的 swing 组件中
【发布时间】:2009-10-07 00:39:28
【问题描述】:

在我的 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"

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

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

【问题讨论】:

    标签: java html swing rtf


    【解决方案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)));
    }
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 感谢您的链接,这看起来更适合拍摄屏幕上已经可见的组件的快照。我想使用“冲压”方法在自定义组件的各个位置呈现样式文本块。
      • 我不知道什么是冲压方法。也许我不明白这个问题,但想法是您可以从不可见的组件创建图像。然后,您可以制作子图像以在您的自定义组件上呈现。关键是您不需要可见组件来创建图像。
      猜你喜欢
      • 1970-01-01
      • 2015-03-14
      • 1970-01-01
      • 2018-09-02
      • 2014-12-20
      • 2013-01-27
      • 1970-01-01
      • 1970-01-01
      • 2011-07-03
      相关资源
      最近更新 更多