2009-10-11 4 views
5

В настоящее время я использую JTextPane, чтобы пользователи могли добавлять/редактировать текст. Он позволяет выделить жирный/курсив/подчеркивание (и я планирую разрешить ссылки в будущем). Он также позволяет пользователям отбрасывать кнопки, которые вставляются в качестве пользовательских стилей. Панель выглядит следующим образом:Как вывести содержимое JTextPane в HTML, включая пользовательский стиль?

< < изображение удалено>>

Я хотел бы, чтобы иметь возможность сохранять содержимое/загрузки в качестве HTML - содержание будет включено в Flash SWF. Я в состоянии получить содержание, как HTML, так как:

 public String getHTMLText(){ 

    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
try{ 
    HTMLEditorKit hk = new HTMLEditorKit(); 
    hk.write(baos, this.getStyledDocument(), 0, this.getDocument().getLength()); 

     } catch (IOException e) { 
     e.printStackTrace(); 
     } catch (BadLocationException e) { 
     e.printStackTrace(); 
     } 
     return baos.toString(); 
    } 

Это прекрасно работает, если JTextPane включает в себя только жирный/курсив/подчеркнутый текст. Однако выход слишком сложный. Я хочу, чтобы иметь возможность вывода мой пользовательский стиль, как хорошо, но когда я пытаюсь я получаю эту ошибку:

Exception occurred during event dispatching: 
    java.lang.NullPointerException 
at javax.swing.text.html.MinimalHTMLWriter.writeAttributes(MinimalHTMLWriter.java:151) 
at javax.swing.text.html.MinimalHTMLWriter.writeStyles(MinimalHTMLWriter.java:256) 
at javax.swing.text.html.MinimalHTMLWriter.writeHeader(MinimalHTMLWriter.java:220) 
at javax.swing.text.html.MinimalHTMLWriter.write(MinimalHTMLWriter.java:122) 
at javax.swing.text.html.HTMLEditorKit.write(HTMLEditorKit.java:293) 
at javax.swing.text.DefaultEditorKit.write(DefaultEditorKit.java:152) 
at numeracy.referencetextpanel.NRefButtonTextArea.getHTMLText(NRefButtonTextArea.java:328) 
at numeracy.referencetextpanel.NInputPanelRefTextButton.getReferencedText(NInputPanelRefTextButton.java:59) 
at numeracy.referencetextpanel.NInputRefText.actionPerformed(NInputRefText.java:106) 
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995) 

Мой пользовательский стиль вставляется как так (ИДС является строкой, как «{} 0-0 "):

StyledDocument doc = this.getStyledDocument(); 

NRefButton b = this.createRefButton(cID); 

Style style = doc.addStyle(cID, null); //prepare a style 
StyleConstants.setComponent(style, b); 

doc.insertString(doc.getLength(), b.toString(), style); //insert button at index 

функция createRefButton (Строка CID):

private NRefButton createRefButton(String cID) { 

    NRefButton b = new NRefButton(_equationButtons.get(cID).getText(), cID, _equationButtons.get(cID).isStruck()); //prepare a button 

    return b; 
} 

NRefButton переопределяет ToString, который возвращает "{" + CID +"}».

Что бы я хотел знать: должен ли я изменить способ ввода «Стиль», чтобы получить эту ошибку?

Есть ли другой/лучший способ получить HTML из этой JTextPane? Все, что я хочу, это HTML-теги вокруг выделенного жирным/курсивом/подчеркнутым текстом, не слишком сложным, как если бы это было тогда, мне нужно будет вырезать ненужный HTML, а для «стиля» - как button.toString().

Или должен ли я реализовать свой собственный метод toHTML(), обертывая полужирным/курсивом/подчеркнутый текст с требуемыми тегами? Я не возражаю против этого (в некотором роде я бы предпочел), но я не знаю, как получить стили для данного документа JTextPane. Я полагаю, что если бы мне удалось получить эти стили, я мог бы перебирать их, обертывая стилизованный текст в соответствующие теги?

В идеале, на фото содержание JTextPane будет выводиться как:

<html><p>This is some <b>styled</b> text. It is <u>incredible</u>. 
<br/> 
<br/> 
Here we have a button that has been dropped in: {0-0}. These buttons are a <b><i>required part of this project.</i></b> 

Я хочу, чтобы иметь возможность чтения вывод HTML в JTextPane, а также - опять же, я не против написания моего собственный методHTML() для этого, но мне нужно сначала получить HTML-код.

Спасибо, что нашли время, чтобы прочитать мой вопрос.

+1

Я не знаю ответа на ваш вопрос, но, пожалуйста, замените этот пользовательский OutputStream на самый высокий голосовой ответ на указанный вопрос, то есть используйте ByteArrayOutputStream. –

+0

Готово, спасибо Дэйв. –

ответ

3

После чтения:

я написал свой собственный HTML-экспортер:

package com.HTMLExport; 

    import javax.swing.text.AbstractDocument; 
    import javax.swing.text.AttributeSet; 
    import javax.swing.text.BadLocationException; 
    import javax.swing.text.Element; 
    import javax.swing.text.ElementIterator; 
    import javax.swing.text.StyleConstants; 
    import javax.swing.text.StyledDocument; 

    public class NHTMLWriter { 

    private StyledDocument _sd; 
    private ElementIterator _it; 

    protected static final char NEWLINE = '\n'; 

    public NHTMLWriter(StyledDocument doc) { 
     _sd = doc; 
     _it = new ElementIterator(doc.getDefaultRootElement()); 
    } 

    public String getHTML(){ 
     return "<html>" + this.getBody() + "</html>"; 
    } 

    protected String getBody() { 
     /* 
      This will be a section element for a styled document. 
      We represent this element in HTML as the body tags. 
       Therefore we ignore it. 
     */ 
     _it.current(); 

     Element next = null; 

     String body = "<body>"; 

     while((next = _it.next()) != null) { 
     if (this.isText(next)) { 
     body += writeContent(next); 
     } 
     else if(next.getName().equals("component")){ 
     body += getText(next); //this is where the custom component is output. 
     } 
     } 
     body += "</body>"; 

     return body; 
    } 
    /** 
     * Returns true if the element is a text element. 
     */ 
    protected boolean isText(Element elem) { 
     return (elem.getName() == AbstractDocument.ContentElementName); 
    } 
    protected String writeContent(Element elem){ 

     AttributeSet attr = elem.getAttributes(); 

    String startTags = this.getStartTag(attr); 

    String content = startTags + this.getText(elem) + this.getEndTag(startTags); 

    return content; 
    } 
    /** 
     * Writes out text 
     */ 
    protected String text(Element elem){ 
     String contentStr = getText(elem); 
     if ((contentStr.length() > 0) && (contentStr.charAt(contentStr.length()-1) == NEWLINE)) { 
     contentStr = contentStr.substring(0, contentStr.length()-1) + "<br/>"; 
     } 
     if (contentStr.length() > 0) { 
     return contentStr; 
     } 
     return contentStr; 
    } 

    protected String getText(Element elem){ 
     try { 
     return _sd.getText(elem.getStartOffset(), elem.getEndOffset() - elem.getStartOffset()).replaceAll(NEWLINE+"", "<br/>"); 
     } catch (BadLocationException e) { 
     e.printStackTrace(); 
     } 
     return ""; 
    } 
    private String getEndTag(String startTags) { 

    String[] startOrder = startTags.split("<"); 

    String tags = ""; 

    for(String s : startOrder){ 
    tags = "</" + s + tags; 
    } 

    return tags; 
    } 
    private String getStartTag(AttributeSet attr) { 

     String tag = ""; 

     if(StyleConstants.isBold(attr)){ 
     tag += "<b>"; 
     } 
     if(StyleConstants.isItalic(attr)){ 
     tag += "<i>"; 
     } 
     if(StyleConstants.isUnderline(attr)){ 
     tag += "<u>"; 
     } 

     return tag; 
    } 
    } 

Нет w Мне нужно написать код, чтобы он мог сделать обратное: конвертирует выходной HTML в StyledDocument.

Во-первых, кофе.

+3

Ницца. Вы спросили, вы прокомментировали, вы ответили и согласились. – Petah

+0

Вы когда-нибудь встречались, чтобы написать вторую половину? – nyxaria

Смежные вопросы