代码之家  ›  专栏  ›  技术社区  ›  Sam Barnum

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

  •  0
  • Sam Barnum  · 技术社区  · 15 年前

    在我的Swing应用程序中,用户在 JTextPane 它使用RTFEditorKit(也可以使用HTML)。

    我认为 View.paint

    我有以下方法:

    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 ,但是文本窗格需要是可见的,这样做感觉是错误的。

    2 回复  |  直到 15 年前
        1
  •  0
  •   camickr    15 年前

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

        2
  •  1
  •   Sam Barnum    15 年前

    这段代码可以正常工作,但似乎不太理想。有更好的方法吗?另外,有什么好方法可以将文本渲染到图形上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)));
    }