6

現在、JTextPane を使用して、ユーザーがテキストを追加/編集できるようにしています。太字/斜体/下線を使用できます (将来的にはリンクを許可する予定です)。また、カスタム スタイルとして挿入されるボタンをドロップすることもできます。パネルは次のようになります。

<< < 画像削除 >>

コンテンツを 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)

私のカスタム スタイルは次のように挿入されます (cID は "{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(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 は、"{"+cID+"}" を返す toString をオーバーライドします。

私が知りたいこと: このエラーを取得するには、「スタイル」を挿入する方法を変更する必要がありますか?

この JTextPane から HTML を取得する別の/より良い方法はありますか? 私が欲しいのは、太字/斜体/下線付きのテキストの周りの 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 に読み込むこともできるようにしたいと考えています。この場合も、独自の fromHTML() メソッドを記述してもかまいませんが、最初に HTML を取得できるようにする必要があります。

私の質問を読んでくれてありがとう。

4

1 に答える 1

4

読んだあと:

独自の 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;
     }
    }

ここで、出力 HTML を StyledDocument に変換するという逆のことができるようにコードを記述する必要があります。

まずはコーヒー。

于 2009-10-12T03:07:27.737 に答える