Question

I have a JEditorPane and I'm trying to edit one fo the html element attributes, basically changing the the src x value in to a custom value

The code I have is:

// Get <img src="..."> tag
RunElement imageTagElement = getImageTagElement(htmlDocument);

// Print src attribute value
System.out.println("src : " + runElement.getAttribute(HTML.Attribute.SRC));

// Replace existing src value 
runElement.removeAttribute(HTML.Attribute.SRC);
runElement.addAttribute(HTML.Attribute.SRC, "customValue");

I get the following exception in the before last line when I try to remove the existing attribute (because you can't replace):

javax.swing.text.StateInvariantError: Illegal cast to MutableAttributeSet

I read a few places that you can use writeLock, but that's a protected method, which means I can't call it from this code...

So basically my question is that if you've found the element you want, how do you edit it's attributes?

Was it helpful?

Solution

The problem is that HtmlDocument requires you perform a writeLock before trying to change any attributes and a writeUnlock after. So to solve this I had to:

First extend the EditorKit for my JEditorPane to use a custom HtmlDocument. Then I extended the HTMLDocument to make the writeLock and writeUnlock publicly accesible:

public class ExtendedHTMLDocument extends HTMLDocument
{
    public void hackWriteLock()
    {
        writeLock();
    }

    public void hackWriteUnlock()
    {
        writeUnlock();
    }
}

Then I did:

public class ExtendedEditorKit extends HTMLEditorKit
{
    @Override
    public Document createDefaultDocument()
    {
        // For the left out code copy what's in the super method
        ..
        HTMLDocument doc = new ExtendedHTMLDocument(ss);
        ..
    }
}

Now I could in code above, all I have to do is call the lock before trying to edit the attributes, and unlock when I'm done:

// lock
htmlDocument.hackWriteLock()

// Get <img src="..."> tag
RunElement imageTagElement = getImageTagElement(htmlDocument);

// Print src attribute value
System.out.println("src : " + runElement.getAttribute(HTML.Attribute.SRC));

// Replace existing src value 
runElement.removeAttribute(HTML.Attribute.SRC);
runElement.addAttribute(HTML.Attribute.SRC, "customValue");

// unlock
htmlDocument.hackWriteUnlock()

And everything works as expected. I'm able to modify and edit the attributes in the document.

I guess what I now don't fully understand or appreciate is why you can't access the writeLock and writeUnlock publicly? Why have they been setup as protected? What where the programmers trying to prevent you from doing and why?

OTHER TIPS

## Use the  htmlDoc.setCharacterAttributes (...);##
ElementIterator it = new ElementIterator(htmlDoc);
Element elem;
 while ((elem = it.next()) != null) {
   if (elem.getName().equals("img")) {
      AttributeSet atts = elem.getAttributes();
       // Modifiable 
      SimpleAttributeSet simple = new SimpleAttributeSet(atts);
      String s = (String) simple.getAttribute(HTML.Attribute.SRC);
      if (s != null) {
           System.out.println(s); // testing
           int len = elem.getEndOffset() - elem.getStartOffset();
           //simple.removeAttribute(HTML.Attribute.SRC);
           simple.addAttribute( HTML.Attribute.SRC, **newSRC_URL_String** );
           //
           //  The doc takes care of the locks 
           //
           htmlDoc.setCharacterAttributes(
             elem.getStartOffset(),len,simple,true);
 }
 }
 }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top