2009-10-04 70 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))); 
}