-
Bug
-
Resolution: Unresolved
-
P4
-
8u102
-
x86_64
-
linux
FULL PRODUCT VERSION :
ADDITIONAL OS VERSION INFORMATION :
Linux icon020 4.4.0-36-generic #55-Ubuntu SMP Thu Aug 11 18:01:55 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
You cannot use your own elements with DefaultStyledDocument although it is supported by its superclass. AbstractDocument defines a "Hook through which elements are created to represent the document structure.":
* protected Element createLeafElement(Element parent, AttributeSet a, int p0, int p1)
* protected Element createBranchElement(Element parent, AttributeSet a)
DefaultStyledDocument is a subclass of AbstractDocument. You cannot subclass DefaultStyledDocument and override those two methods because DefaultStyledDocument creates the elements in an own way in createDefaultRoot().
Please use createLeafElement and createBranchElement in DefaultStyledDocument#createDefaultRoot and add a method createSectionElement() to not break this hook defined by AbstractDocument.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
* Subclass DefaultStyledDocument
* Override createLeafElement and createBranchElement
* Your code is not run in createDefaultRoot and so you cannot replace the complete document structure
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I would expect that it is possible to override the createLeafElement and createBranchElement methods to return own elements (for example subclasses of LeafElement and BranchElement to enhance the elements with own behaviour / data).
ACTUAL -
It is possible to override the methods but they are not used for creating all elements of the document. At least createDefaultRoot fails to use the create methods.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.UUID;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AbstractDocument.BranchElement;
import javax.swing.text.AbstractDocument.LeafElement;
import javax.swing.text.AttributeSet;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Document;
import javax.swing.text.Element;
public class Main {
public static void main(final String[] args) {
final JFrame f = new JFrame();
f.setBounds(100, 100, 500, 500);
final JEditorPane editor = new JEditorPane();
editor.setDocument(new DefaultStyledDocument(){
@Override
protected Element createBranchElement(final Element parent, final AttributeSet a) {
return new Branch(this, parent, a);
}
@Override
protected Element createLeafElement(final Element parent, final AttributeSet a, final int p0, final int p1) {
return new Leaf(this, parent, a, p0, p1);
}
});
f.setContentPane(editor);
editor.getDocument().addDocumentListener(new DocumentListener(){
@Override
public void removeUpdate(final DocumentEvent e) {
update();
}
@Override
public void insertUpdate(final DocumentEvent e) {
update();
}
@Override
public void changedUpdate(final DocumentEvent e) {
update();
}
private void update() {
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
final Document doc = editor.getDocument();
for (final Element rootElement : doc.getRootElements()) {
print(0, rootElement);
}
System.out.println("---");
}
});
}
});
f.setVisible(true);
}
public static String repeat(final char ch, final int repeat) {
final char[] buf = new char[repeat];
for (int i = repeat - 1; i >= 0; i--) {
buf[i] = ch;
}
return new String(buf);
}
private static void print(final int i, final Element element) {
System.out.println(repeat(' ', i) + idOf(element));
for (int j = 0; j < element.getElementCount(); ++j) {
print(i + 1, element.getElement(j));
}
}
private static String idOf(final Element element) {
String id = "";
if (element instanceof Branch) {
id += "Branch: " + ((Branch)element).id();
} else if (element instanceof Leaf) {
id += "Leaf: " + ((Leaf)element).id();
} else {
id += "FIXME: " + String.valueOf(element);
}
return id;
}
static class Branch extends BranchElement {
public Branch(final AbstractDocument abstractDocument, final Element parent, final AttributeSet a) {
abstractDocument.super(parent, a);
}
private final Object id = UUID.randomUUID();
public String id() {
return this.id.toString();
}
}
static class Leaf extends LeafElement {
public Leaf(final AbstractDocument abstractDocument,
final Element parent,
final AttributeSet a,
final int offs0,
final int offs1) {
abstractDocument.super(parent, a, offs0, offs1);
}
private final Object id = UUID.randomUUID();
public String id() {
return this.id.toString();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
One can override createDefaultRoot and use the correct methods. But that results in deadlocks..
Also one might copy DefaultStyledDocument and subclass AbstractDocument directly but with the copied source code of DefaultStyledDocument.
ADDITIONAL OS VERSION INFORMATION :
Linux icon020 4.4.0-36-generic #55-Ubuntu SMP Thu Aug 11 18:01:55 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
You cannot use your own elements with DefaultStyledDocument although it is supported by its superclass. AbstractDocument defines a "Hook through which elements are created to represent the document structure.":
* protected Element createLeafElement(Element parent, AttributeSet a, int p0, int p1)
* protected Element createBranchElement(Element parent, AttributeSet a)
DefaultStyledDocument is a subclass of AbstractDocument. You cannot subclass DefaultStyledDocument and override those two methods because DefaultStyledDocument creates the elements in an own way in createDefaultRoot().
Please use createLeafElement and createBranchElement in DefaultStyledDocument#createDefaultRoot and add a method createSectionElement() to not break this hook defined by AbstractDocument.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
* Subclass DefaultStyledDocument
* Override createLeafElement and createBranchElement
* Your code is not run in createDefaultRoot and so you cannot replace the complete document structure
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I would expect that it is possible to override the createLeafElement and createBranchElement methods to return own elements (for example subclasses of LeafElement and BranchElement to enhance the elements with own behaviour / data).
ACTUAL -
It is possible to override the methods but they are not used for creating all elements of the document. At least createDefaultRoot fails to use the create methods.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.UUID;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AbstractDocument.BranchElement;
import javax.swing.text.AbstractDocument.LeafElement;
import javax.swing.text.AttributeSet;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Document;
import javax.swing.text.Element;
public class Main {
public static void main(final String[] args) {
final JFrame f = new JFrame();
f.setBounds(100, 100, 500, 500);
final JEditorPane editor = new JEditorPane();
editor.setDocument(new DefaultStyledDocument(){
@Override
protected Element createBranchElement(final Element parent, final AttributeSet a) {
return new Branch(this, parent, a);
}
@Override
protected Element createLeafElement(final Element parent, final AttributeSet a, final int p0, final int p1) {
return new Leaf(this, parent, a, p0, p1);
}
});
f.setContentPane(editor);
editor.getDocument().addDocumentListener(new DocumentListener(){
@Override
public void removeUpdate(final DocumentEvent e) {
update();
}
@Override
public void insertUpdate(final DocumentEvent e) {
update();
}
@Override
public void changedUpdate(final DocumentEvent e) {
update();
}
private void update() {
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
final Document doc = editor.getDocument();
for (final Element rootElement : doc.getRootElements()) {
print(0, rootElement);
}
System.out.println("---");
}
});
}
});
f.setVisible(true);
}
public static String repeat(final char ch, final int repeat) {
final char[] buf = new char[repeat];
for (int i = repeat - 1; i >= 0; i--) {
buf[i] = ch;
}
return new String(buf);
}
private static void print(final int i, final Element element) {
System.out.println(repeat(' ', i) + idOf(element));
for (int j = 0; j < element.getElementCount(); ++j) {
print(i + 1, element.getElement(j));
}
}
private static String idOf(final Element element) {
String id = "";
if (element instanceof Branch) {
id += "Branch: " + ((Branch)element).id();
} else if (element instanceof Leaf) {
id += "Leaf: " + ((Leaf)element).id();
} else {
id += "FIXME: " + String.valueOf(element);
}
return id;
}
static class Branch extends BranchElement {
public Branch(final AbstractDocument abstractDocument, final Element parent, final AttributeSet a) {
abstractDocument.super(parent, a);
}
private final Object id = UUID.randomUUID();
public String id() {
return this.id.toString();
}
}
static class Leaf extends LeafElement {
public Leaf(final AbstractDocument abstractDocument,
final Element parent,
final AttributeSet a,
final int offs0,
final int offs1) {
abstractDocument.super(parent, a, offs0, offs1);
}
private final Object id = UUID.randomUUID();
public String id() {
return this.id.toString();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
One can override createDefaultRoot and use the correct methods. But that results in deadlocks..
Also one might copy DefaultStyledDocument and subclass AbstractDocument directly but with the copied source code of DefaultStyledDocument.