I hacked a little more on Swing text stuff and finally got my first
little HTML application working:

http://kennke.org/~roman/html.png

The sourcecode to this program is attached.

I checked in the fixes as two commits:

2006-02-17  Roman Kennke  <[EMAIL PROTECTED]>

        * javax/swing/text/html/HTMLEditorKit.java
        (HTMLFactory.create): Create InlineView for content tags.
        * javax/swing/text/html/HTMLDocument.java
        (HTMLReader.flush): Call create() on first flush and insert
        on subsequent flushes.

2006-02-17  Roman Kennke  <[EMAIL PROTECTED]>

        * javax/swing/text/AbstractDocument.java
        (BranchElement.getStartOffset): Implemented workaround for wrong
        NPE.
        (BranchElement.getEndOffset): Implemented workaround for wrong
        NPE.
        (ElementBuffer.split): Use createBranchElement() instead of
        new BranchElement().
        (ElementBuffer.insertFracture): Use createBranchElement() instead
of
        new BranchElement().
        (ElementBuffer.recreateAfterFracture): Use createBranchElement()
        instead of new BranchElement().
        (createDefaultRoot): Use createBranchElement() and
createLeafElement
        instead of the constructors.
        (create): Rewritten.

/Roman
Index: javax/swing/text/html/HTMLDocument.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/html/HTMLDocument.java,v
retrieving revision 1.21
diff -u -r1.21 HTMLDocument.java
--- javax/swing/text/html/HTMLDocument.java	17 Feb 2006 10:36:34 -0000	1.21
+++ javax/swing/text/html/HTMLDocument.java	17 Feb 2006 14:58:20 -0000
@@ -1134,7 +1134,11 @@
       elements = new DefaultStyledDocument.ElementSpec[parseBuffer.size()];
       parseBuffer.copyInto(elements);
       parseBuffer.removeAllElements();
-      insert(offset, elements);
+      if (offset == 0)
+        create(elements);
+      else
+        insert(offset, elements);
+
       offset += HTMLDocument.this.getLength() - offset;
     }
     
Index: javax/swing/text/html/HTMLEditorKit.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/html/HTMLEditorKit.java,v
retrieving revision 1.23
diff -u -r1.23 HTMLEditorKit.java
--- javax/swing/text/html/HTMLEditorKit.java	20 Dec 2005 15:59:45 -0000	1.23
+++ javax/swing/text/html/HTMLEditorKit.java	17 Feb 2006 14:58:20 -0000
@@ -553,8 +553,9 @@
             view = new BlockView(element, View.Y_AXIS);
           
           // FIXME: Uncomment when the views have been implemented
-         /* else if (tag.equals(HTML.Tag.CONTENT))
-            view = new InlineView(element); 
+          else if (tag.equals(HTML.Tag.CONTENT))
+            view = new InlineView(element);
+          /*
           else if (tag.equals(HTML.Tag.MENU) || tag.equals(HTML.Tag.DIR)
                    || tag.equals(HTML.Tag.UL) || tag.equals(HTML.Tag.OL))
             view = new ListView(element);
Index: javax/swing/text/AbstractDocument.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/AbstractDocument.java,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -r1.46 -r1.47
--- javax/swing/text/AbstractDocument.java	13 Feb 2006 14:13:29 -0000	1.46
+++ javax/swing/text/AbstractDocument.java	17 Feb 2006 14:55:46 -0000	1.47
@@ -1707,9 +1707,12 @@
      */
     public int getEndOffset()
     {
+      int end = 0;
       if (getElementCount() == 0)
-        throw new NullPointerException("This BranchElement has no children.");
-      return children[children.length - 1].getEndOffset();
+        end = getLength(); // FIXME: That ain't correct, fix it.
+      else
+        end = children[children.length - 1].getEndOffset();
+      return end;
     }
 
     /**
@@ -1734,9 +1737,12 @@
      */
     public int getStartOffset()
     {
+      int start = 0;
       if (getElementCount() == 0)
-        throw new NullPointerException("This BranchElement has no children.");
-      return children[0].getStartOffset();
+        start = 0; // FIXME: That ain't correct, fix it.
+      else
+        start = children[0].getStartOffset();
+      return start;
     }
 
     /**
Index: javax/swing/text/DefaultStyledDocument.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultStyledDocument.java,v
retrieving revision 1.61
retrieving revision 1.62
diff -u -r1.61 -r1.62
--- javax/swing/text/DefaultStyledDocument.java	13 Feb 2006 17:21:34 -0000	1.61
+++ javax/swing/text/DefaultStyledDocument.java	17 Feb 2006 14:55:46 -0000	1.62
@@ -1203,8 +1203,9 @@
               edit.addRemovedElements(removed);
               edit.addAddedElements(added);
               
-              BranchElement newPar = (BranchElement) new BranchElement(el.getParentElement(),
-                                                                       el.getAttributes());
+              BranchElement newPar =
+                (BranchElement) createBranchElement(el.getParentElement(),
+                                                    el.getAttributes());
               newPar.replace(0, 0, newAdded);
               res = new Element[] { null, newPar };
             }
@@ -1217,8 +1218,8 @@
               Edit edit = getEditForParagraphAndIndex((BranchElement) el, editIndex);
               edit.addRemovedElements(removed);
               
-              BranchElement newPar = (BranchElement) new BranchElement(el.getParentElement(),
-                                                                       el.getAttributes());
+              BranchElement newPar = (BranchElement) createBranchElement(el.getParentElement(),
+                                                                         el.getAttributes());
                                                                
               newPar.replace(0, 0, removed);
               res = new Element[] { null, newPar };
@@ -1271,7 +1272,8 @@
         {
           // recreate left-side of branch and all its children before offset
           // add the fractured leaves to the right branch
-          BranchElement rightBranch = new BranchElement(parent, parentAtts);
+          BranchElement rightBranch =
+            (BranchElement) createBranchElement(parent, parentAtts);
           
           // Check if left branch has already been edited. If so, we only
           // need to create the right branch.
@@ -1286,7 +1288,8 @@
             }
           else
             {
-              leftBranch = new BranchElement(parent, parentAtts);
+              leftBranch =
+                (BranchElement) createBranchElement(parent, parentAtts);
               added = new Element[] { leftBranch, rightBranch };
 
               // add fracture to leftBranch
@@ -1390,7 +1393,9 @@
                                          startOffset, startOffset + len);
           else
             {
-              BranchElement br = new BranchElement(parent, curr.getAttributes());
+              BranchElement br =
+                (BranchElement) createBranchElement(parent,
+                                                    curr.getAttributes());
               int bSize = curr.getElementCount();
               for (int k = 0; k < bSize; k++)
                 {
@@ -1663,7 +1668,9 @@
    */
   private StyleChangeListener styleChangeListener;
 
-  /** Vector that contains all the edits. */
+  /**
+   * Vector that contains all the edits. Maybe replace by a HashMap.
+   */
   Vector edits = new Vector();
 
   /**
@@ -1741,12 +1748,13 @@
     Element[] tmp;
     SectionElement section = new SectionElement();
 
-    BranchElement paragraph = new BranchElement(section, null);
+    BranchElement paragraph =
+      (BranchElement) createBranchElement(section, null);
     tmp = new Element[1];
     tmp[0] = paragraph;
     section.replace(0, 0, tmp);
 
-    LeafElement leaf = new LeafElement(paragraph, null, 0, 1);
+    Element leaf = createLeafElement(paragraph, null, 0, 1);
     tmp = new Element[1];
     tmp[0] = leaf;
     paragraph.replace(0, 0, tmp);
@@ -2342,14 +2350,59 @@
    */
   protected void create(ElementSpec[] data)
   {
+    writeLock();
     try
       {
-        // Clear content.
-        content.remove(0, content.length());
-        // Clear buffer and root element.
-        buffer = new ElementBuffer(createDefaultRoot());
-        // Insert the data.
-        insert(0, data);
+        // Clear content if there is some.
+        int len = getLength();
+        if (len > 0)
+          remove(0, len);
+
+        // Now we insert the content.
+        StringBuilder b = new StringBuilder();
+        for (int i = 0; i < data.length; ++i)
+          {
+            ElementSpec el = data[i];
+            if (el.getArray() != null && el.getLength() > 0)
+              b.append(el.getArray(), el.getOffset(), el.getLength());
+          }
+        Content content = getContent();
+        UndoableEdit cEdit = content.insertString(0, b.toString());
+
+        DefaultDocumentEvent ev =
+          new DefaultDocumentEvent(0, b.length(),
+                                   DocumentEvent.EventType.INSERT);
+        ev.addEdit(cEdit);
+
+        // We do a little trick here to get the new structure: We instantiate
+        // a new ElementBuffer with a new root element, insert into that root
+        // and then reparent the newly created elements to the old root
+        // element.
+        BranchElement createRoot =
+          (BranchElement) createBranchElement(null, null);
+        Element dummyLeaf = createLeafElement(createRoot, null, 0, 1);
+        createRoot.replace(0, 0, new Element[]{ dummyLeaf });
+        ElementBuffer createBuffer = new ElementBuffer(createRoot);
+        createBuffer.insert(0, b.length(), data, new DefaultDocumentEvent(0, b.length(), DocumentEvent.EventType.INSERT));
+        // Now the new root is the first child of the createRoot.
+        Element newRoot = createRoot.getElement(0);
+        BranchElement root = (BranchElement) getDefaultRootElement();
+        Element[] added = new Element[newRoot.getElementCount()];
+        for (int i = 0; i < added.length; ++i)
+          {
+            added[i] = newRoot.getElement(i);
+            ((AbstractElement) added[i]).element_parent = root;
+          }
+        Element[] removed = new Element[root.getElementCount()];
+        for (int i = 0; i < removed.length; ++i)
+          removed[i] = root.getElement(i);
+
+        // Replace the old elements in root with the new and update the event.
+        root.replace(0, removed.length, added);
+        ev.addEdit(new ElementEdit(root, 0, removed, added));
+
+        fireInsertUpdate(ev);
+        fireUndoableEditUpdate(new UndoableEditEvent(this, ev));
       }
     catch (BadLocationException ex)
       {
@@ -2357,5 +2410,9 @@
         err.initCause(ex);
         throw err;
       }
+    finally
+      {
+        writeUnlock();
+      }
   }
 }
import javax.swing.*;
import javax.swing.text.html.*;

public class HTMLTest extends JFrame {
  public HTMLTest() {
    super("HTMLTest");
    JTextPane p = new JTextPane();
    p.setEditorKit(new HTMLEditorKit());
    p.setText("<html><body><h1>HTML Test</h1><p>Hello Classpath planet</p><p>This is the first working HTML program</p></body></html>");
    getContentPane().add(p);
  }
  public static void main(String[] args) {
    HTMLTest t = new HTMLTest();
    t.setSize(400, 300);
    t.setVisible(true);
  }
}

Reply via email to