2009-10-11 4 views
5

Attualmente utilizzo un JTextPane per consentire agli utenti di aggiungere/modificare testo. Permette grassetto/corsivo/sottolineato (e ho intenzione di consentire collegamenti in futuro). Consente inoltre agli utenti di rilasciare i pulsanti, che vengono inseriti come stili personalizzati. Il pannello si presenta come:Come stampare contenuti in stile JTextPane in HTML, incluso lo stile personalizzato?

< < immagine cancellato>>

mi piacerebbe essere in grado di salvare il contenuto/carico come HTML - il contenuto sarà incorporato in un file SWF Flash. Sono in grado di ottenere contenuti come HTML in questo modo:

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

Questo funziona bene se il JTextPane include solo/corsivo/testo sottolineato in grassetto. L'output è troppo complicato però. Voglio essere in grado di emettere il mio stile personalizzato pure, ma quando provo sto ottenendo questo errore:

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) 

mio stile personalizzato è inserito in questo modo (CID è una stringa come "{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 funzione 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 ignora toString, che restituisce "{" + CID +"}".

Cosa mi piacerebbe sapere: dovrei modificare il modo in cui inserisco lo "Stile" per ottenere questo errore?

C'è un modo diverso/migliore per ottenere HTML da questo JTextPane? Tutto quello che voglio sono i tag HTML intorno al testo in grassetto/corsivo/sottolineato, non eccessivamente complicato come se dovessi poi spogliare l'HTML non necessario, e per lo "stile" uscire come button.toString().

Oppure devo implementare il mio metodo toHTML(), inserendo il testo in grassetto/corsivo/sottolineato con i tag richiesti? Non mi dispiace farlo (in un certo senso lo preferirei), ma non so come ottenere gli stili per il documento JTextPane dato. Suppongo che se fossi in grado di ottenere questi stili, potrei scorrere attraverso di loro, avvolgendo il testo in stile nei tag appropriati?

Idealmente, il contenuto JTextPane nella foto sarebbe uscita come:

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

voglio essere in grado di leggere l'output HTML in la JTextPane così - ancora una volta non mi dispiace scrivere il mio possedere il metodo fromHTML() per questo, ma prima devo essere in grado di estrarre l'HTML.

Grazie per aver trovato il tempo di leggere la mia domanda.

+1

Non conosco la risposta alla tua domanda, ma per favore sostituisci OutputStream personalizzato con la risposta più votata alla domanda di riferimento, ad esempio ByteArrayOutputStream. –

+0

Fatto, grazie Dave. –

risposta

3

Dopo la lettura:

ho scritto la mia esportatore 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; 
    } 
    } 

No w Ho bisogno di scrivere il codice in modo che possa fare il contrario: converte l'output HTML in uno StyledDocument.

Innanzitutto, caffè.

+3

Bello. Hai chiesto, hai commentato, hai risposto e hai accettato. – Petah

+0

Sei mai riuscito a scrivere l'altra metà? – nyxaria