2009-10-11 11 views
5

Actualmente uso un JTextPane para permitir a los usuarios agregar/editar texto. Permite negrita/cursiva/subrayado (y planeo permitir enlaces en el futuro). También permite a los usuarios soltar botones, que se insertan como estilos personalizados. El panel se ve así:Cómo generar contenido de estilo JTextPane en HTML, incluido el estilo personalizado?

< < imagen eliminada>>

Me gustaría ser capaz de guardar el contenido/carga como HTML - el contenido se incorpora en un SWF de Flash. Soy capaz de obtener el contenido como HTML así:

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

Esto funciona bien si el JTextPane incluye sólo negrita cursiva/texto/subrayado. Sin embargo, la salida es demasiado complicada. Quiero ser capaz de salida de mi estilo personalizado así, pero cuando trato que estoy recibiendo este error:

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) 

Mi estilo personalizado se inserta como tal (Cid es una cadena como "{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 

La función createRefButton (String 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 anula toString, que devuelve "{" + CID +"}".

Lo que me gustaría saber: ¿debería modificar la forma en que inserto el "Estilo" para obtener este error?

¿Hay alguna manera diferente/mejor para obtener HTML de este JTextPane? Todo lo que quiero es etiquetas HTML alrededor de texto en negrita/cursiva/subrayado, no demasiado complicado como si fuera así, tendré que quitar el HTML innecesario y que el "estilo" salga como button.toString().

¿O debería implementar mi propio método toHTML(), envolviendo el texto en negrita/cursiva/subrayado con las etiquetas requeridas? No me importa hacer esto (de alguna manera lo preferiría), pero no sé cómo obtener los estilos para el documento JTextPane dado. Supongo que si pudiera obtener estos estilos, podría iterar a través de ellos, envolviendo texto con estilo en las etiquetas apropiadas.

Idealmente, el contenido JTextPane representado sería salida como:

<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> 

Quiero ser capaz de leer la salida HTML en el JTextPane así - de nuevo no me importa escribir mi propio del método HTML() para esto, pero necesito poder sacar HTML primero.

Gracias por tomarse el tiempo para leer mi pregunta.

+1

No conozco la respuesta a su pregunta, pero reemplace ese OutputStream personalizado con la respuesta más votada a la pregunta a la que se hace referencia, es decir, use ByteArrayOutputStream. –

+0

Hecho, gracias Dave. –

Respuesta

3

Después de leer:

me escribió mi propio exportador 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; 
    } 
    } 

n w Necesito escribir un código para que pueda hacer lo contrario: convierte el HTML de salida en un StyledDocument.

Primero, café.

+3

Bueno. Usted preguntó, usted comentó, respondió y aceptó. – Petah

+0

¿Alguna vez escribiste la otra mitad? – nyxaria

Cuestiones relacionadas