Нарисуйте строки RTF / HTML в пользовательский компонент Swing - PullRequest
0 голосов
/ 04 октября 2009

В моем приложении 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, но текстовая панель должна быть видимой, и это похоже на неправильный способ сделать это.

Есть ли способ получить визуальное представление содержимого RTF без рендеринга фактического JTextPane?

Ответы [ 2 ]

1 голос
/ 04 октября 2009

Этот код вроде работает, но кажется не идеальным. Есть ли лучший способ сделать это? Кроме того, каков хороший способ отрисовки текста где-нибудь, кроме 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)));
}
0 голосов
/ 04 октября 2009

Проверьте класс ScreenImage , который позволяет вам создавать BufferedImage любого компонента Swing. Он также должен работать для компонентов Swing, которые не видны, но да, вам нужно сначала выполнить рендеринг.

...