2009-10-04 49 views
0

在我的Swing应用程序中,用户将样式文本输入到使用RTFEditorKit(HTML也是可能性)的JTextPane中。将RTF/HTML字符串绘制成自定义的swing组件

然后,我需要在自定义组件中的特定坐标上渲染许多这些样式的笔记。

我认为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 = {[email protected]}"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 = {[email protected]}"java.awt.Rectangle[x=0,y=0,width=0,height=0]" 
parent = null 
elem = {[email protected]}"BranchElement(section) 0,35\n" 

注意,父= null并且nchildren = 0。这意味着没有什么真正有用的。我可以通过调用JTextPane.getUI().paint来破解一些东西,但文本窗格需要可见,而这种感觉就像是错误的方式。

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

回答

0

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

+0

感谢您的链接,这看起来更适合拍摄已在屏幕上可见的组件快照。我想使用“加盖”方法在自定义组件的各个位置呈现样式化文本块。 – 2009-10-05 16:05:45

+0

我不知道什么是冲压评估。也许我不明白这个问题,但想法是你可以从一个不可见的组件创建一个图像。然后,您可以将子图像呈现在自定义组件上。关键是你不需要一个可见的组件来创建图像。 – camickr 2009-10-05 17:43:24

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