2011-09-30 105 views
3

我與JEditorPane相信。我需要簡單的編輯器。我已經解決了加載和修改包含自定義(兩個)標籤的HTML的問題(請參閱my older post)。它正確顯示文檔,我現在甚至可以編輯它。我可以寫文字,刪除字符或我的自定義元素。我贏得了一場戰鬥,但還沒有贏得戰爭。令人遺憾的是,下一步也是非常有問題的。我無法插入自定義標籤。JEditorPane,HTMLEditorKit - 自定義動作插入自定義標記

我有一個自定義操作:

import my.own.HTMLEditorKit; //extends standard HTMLEditorKit 
import my.own.HTMLDocument; //extends standard HTMLDocument 

class InsertElementAction extends StyledTextAction { 
    private static final long serialVersionUID = 1L; 

    public InsertElementAction(String actionName) { 
     super(actionName); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     JEditorPane editor = getEditor(e); 

     if (editor == null) 
      return; 

     HTMLDocument doc = (HTMLDocument) editor.getDocument(); 
     HTMLEditorKit ekit = (HTMLEditorKit) editor.getEditorKit(); 
     int offset = editor.getSelectionStart(); 

     try { 
      ekit.insertHTML(doc, offset, "<span>ahoj</span>", 0, 0, HTML.Tag.SPAN); 
      Element ele = doc.getRootElements()[0]; 
      ele = ele.getElement(1).getElement(0); 
      doc.setInnerHTML(ele, "<bar medium=\"#DEFAULT\" type=\"packaged\" source=\"identifier\" />"); 
     } 
     catch (BadLocationException ble) { 
      throw new Error(ble); 
     } 
     catch (IOException ioe) { 
      throw new Error(ioe); 
     } 
    } 
} 

它workts正常。我可以插入span元素。但是我不能用這種方式插入非標準標籤。我只能插入codespan等,但不能插入我的標籤。對於我的標籤我被迫使用:

ekit.insertHTML(doc, offset, "x<bar medium=\"#DEFAULT\" type=\"packaged\" source=\"identifier\" />x", 0, 0, null); 

有兩個關鍵問題

  1. 自定義標籤必須與非whispace字符(在此,x)
  2. 來界定當前元素的當我插入span元素爲<p>paragraph</p>體拆分

,我得到<p>par<span>ahoj</span>agraph</p>預期。如何將未知標籤全部插入body元素的子元素中,結果(例如未知標籤x)爲<p>par</p><x>ahoj</x><p>agraph</p>

這項工作讓人筋疲力盡。自從幾周以來,我就相信這個相對簡單的任務。我已經浪費了。如果插入不上班,我就廢了...所有

+1

什麼對象類型是'AppErrors.EDITORKIT_ACTIONFAILURE'?如果'String',爲什麼不拋出新的Throwable(AppErrors.EDITORKIT_ACTIONFAILURE,ioe);'? –

+0

沒關係。我已將帖子更新爲更全面。 –

+0

我不確定我是否理解。 HTMLEditorKit用於呈現HTML。如果您使用非HTML標記提供它,您希望它做什麼? –

回答

1

我已經找到了解決辦法。該標籤被插入這樣:

ModifiedHTMLDocument doc = (ModifiedHTMLDocument) editor.getDocument(); 
int offset = editor.getSelectionStart(); 
//insert our special tag (if the tag is not bounded with non-whitespace character, nothing happens) 
doc.insertHTML(offset, "-<specialTag />-"); 
//remove leading and trailing minuses 
doc.remove(offset, 1); //at the current position is the minus before tag inserted 
doc.remove(offset + 1, 1); //the next sign is minus after new tag (the tag is nowhere) 
//Note: no, you really cannot do that: doc.remove(offset, 2), because then the tag is deleted 

ModifiedHTMLDocument包含方法insertHTML(),它調用由反射隱藏medhod:

public void insertHTML(int offset, String htmlText) throws BadLocationException, IOException { 
    if (getParser() == null) 
     throw new IllegalStateException("No HTMLEditorKit.Parser"); 

    Element elem = getCurrentElement(offset); 

    //the method insertHTML is not visible 
    try { 
     Method insertHTML = javax.swing.text.html.HTMLDocument.class.getDeclaredMethod("insertHTML", 
       new Class[] {Element.class, int.class, String.class, boolean.class}); 
     insertHTML.setAccessible(true); 
     insertHTML.invoke(this, new Object[] {elem, offset, htmlText, false}); 
    } 
    catch (Exception e) { 
     throw new IOException("The method insertHTML() could not be invoked", e); 
    } 
} 

我們的磚框的最後一塊是一種方法尋找當前元素:

public Element getCurrentElement(int offset) { 
    ElementIterator ei = new ElementIterator(this); 
    Element elem, currentElem = null; 
    int elemLength = Integer.MAX_VALUE; 

    while ((elem = ei.next()) != null) { //looking for closest element 
     int start = elem.getStartOffset(), end = elem.getEndOffset(), len = end - start; 
     if (elem.isLeaf() || elem.getName().equals("html")) 
      continue; 
     if (start <= offset && offset < end && len <= elemLength) { 
      currentElem = elem; 
      elemLength = len; 
     } 
    } 

    return currentElem; 
} 

此方法也是ModifiedHTMLDocument類的成員。

該解決方案不純,但它暫時解決了這個問題。我希望我會找到更好的套件。我正在考慮JWebEngine。這應該是目前可憐的HTMLEditorKit的替代品,但我不知道,它是否允許我添加自定義標籤。

2
+0

我在你的帖子的幫助下開始了。但我的東西,還沒有什麼可以添加。這是如何加載包含未知標籤的文件的解決方案。在加載文件後插入自定義標籤有沒有一些經驗?爲了能夠編輯超文本,我必須能夠將我的自定義標記插入到已在我的編輯器窗格中加載的文檔中。不幸的是,這非常困難。 –

+0

當你插入HTML時,應調用相同的方法。所以你的標籤將被識別並創建適當的結構。 – StanislavL

+0

也許,然而'insertHTML()'方法(在我看來是無意識的)隱藏爲私有方法。我只能使用'insertBeforeStart()'等等。儘管如此,當我嘗試時,'setInnerHTML()'方法做了什麼,它只有在標籤被一些非白色字符包裝時才起作用。否則它不會採取任何行動。這似乎有點有趣,讓我感到困惑...... –