The goal:
Working with a JEditorPane and HTMLDocuments I need to react to the removal of images, i.e. Elements defined by <img>..</img>
tags.
What I tried:
For now I use DocumentListeners to react to DocumentEvents which are fired upon changes to a document. Unfortunately, DocumentEvents do not directly contain information about the changed content, so I can't identify what kind of element has been removed. It seems all I can do is iterate over all Elements of the document and call the events getChange(Element).
document.addDocumentListener(new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent arg0) {
ElementIterator iter = new ElementIterator(document);
Element element;
while ((element=iter.next()) != null) {
ElementChange change = arg0.getChange(element);
if (change != null) {
Element[] children = change.getChildrenRemoved();
for (Element child : children) {
Object name = child.getAttributes().getAttribute(StyleConstants.NameAttribute);
System.out.println((HTML.Tag)name);
}
}
}
notifyContentChanged();
}
});
}
Although this solution works partially (sometimes when deleting an image the sysout reports a p-implied
instead of a img
) I would really appreciate other solutions. Probably, someone knows a simple way of getting the String
associated with a change in the document?
SOLUTION
In accordance to the accepted answer, the following code demonstrates the use of DocumentFilters as Listeners (for image removal in this case).
document.setDocumentFilter(new DocumentFilter() {
@Override
public void remove(FilterBypass fb, int offset, int length)
throws BadLocationException {
if (document.getCharacterElement(offset).getName().equals(HTML.Tag.IMG.toString())) {
.
.
}
super.remove(fb, offset, length);
}
});
DocumentEvent has getOffset() and getLength() methods. Normally images are leaves so you can use htmlDocument.getCharacterElement() from the range of change and check whether they are images.
UPDATE: as result of discusing in commetns
You can add a DocumentFilter overriding remove() and use it as listener to get deleted fragment (in fact fragment to-be-deleted).