FULL PRODUCT VERSION :
ADDITIONAL OS VERSION INFORMATION :
Linux localhost 3.10.54-server-2.mga3 #1 SMP Sat Sep 13 14:48:19 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
It seems that parent views loose their children views when the document I18n property is true. Then the display of children views is wrong.
However, children have still their parents.
This bug breaks the compatibility between the 2 options : I18n true and I18N false.
When I18n true GlyphPainter2 is used.
When I18n false GlyphPainter1 is used.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
In the example, in the CodeBugDocument()
Put the document I18n property false :
putProperty("i18n", Boolean.FALSE);
the display is right (a text with a table).
Put the document I18n property true :
putProperty("i18n", Boolean.TRUE);
the display is wrong (a text with a table that looses its lines).
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package CodeBug;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Shape;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.text.*;
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
public class CodeBug extends JFrame {
JEditorPane edit = new JEditorPane();
public CodeBug() {
super("Code example for a TableView bug");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
edit.setEditorKit(new CodeBugEditorKit());
initCodeBug();
this.getContentPane().add(new JScrollPane(edit));
this.setSize(300, 200);
this.setLocationRelativeTo(null);
}
private void initCodeBug() {
CodeBugDocument doc = (CodeBugDocument) edit.getDocument();
try {
doc.insertString(0, "TextB TextE", null);
} catch (BadLocationException ex) {
}
doc.insertTable(6, 4, 3);
try {
doc.insertString(7, "Cell11", null);
doc.insertString(14, "Cell12", null);
doc.insertString(21, "Cell13", null);
doc.insertString(28, "Cell21", null);
doc.insertString(35, "Cell22", null);
doc.insertString(42, "Cell23", null);
doc.insertString(49, "Cell31", null);
doc.insertString(56, "Cell32", null);
doc.insertString(63, "Cell33", null);
doc.insertString(70, "Cell41", null);
doc.insertString(77, "Cell42", null);
doc.insertString(84, "Cell43", null);
} catch (BadLocationException ex) {
}
}
public static void main(String[] args) {
CodeBug m = new CodeBug();
m.setVisible(true);
}
}
//-------------------------------------------------------------------------------
class CodeBugEditorKit extends StyledEditorKit {
ViewFactory defaultFactory = new TableFactory();
@Override
public ViewFactory getViewFactory() {
return defaultFactory;
}
@Override
public Document createDefaultDocument() {
return new CodeBugDocument();
}
}
//-------------------------------------------------------------------------------
class TableFactory implements ViewFactory {
@Override
public View create(Element elem) {
String kind = elem.getName();
if (kind != null) {
if (kind.equals(AbstractDocument.ContentElementName)) {
return new LabelView(elem);
} else if (kind.equals(AbstractDocument.ParagraphElementName)) {
return new ParagraphView(elem);
} else if (kind.equals(AbstractDocument.SectionElementName)) {
return new BoxView(elem, View.Y_AXIS);
} else if (kind.equals(StyleConstants.ComponentElementName)) {
return new ComponentView(elem);
} else if (kind.equals(CodeBugDocument.ELEMENT_TABLE)) {
return new tableView(elem);
} else if (kind.equals(StyleConstants.IconElementName)) {
return new IconView(elem);
}
}
// default to text display
return new LabelView(elem);
}
}
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
class tableView extends TableView implements ViewFactory {
public tableView(Element elem) {
super(elem);
}
@Override
public ViewFactory getViewFactory() {
return this;
}
@Override
public float getMinimumSpan(int axis) {
return getPreferredSpan(axis);
}
@Override
public float getMaximumSpan(int axis) {
return getPreferredSpan(axis);
}
@Override
public float getAlignment(int axis) {
return 0.5f;
}
@Override
public void paint(Graphics g, Shape allocation) {
super.paint(g, allocation);
Rectangle alloc = allocation.getBounds();
int lastY = alloc.y + alloc.height - 1;
g.drawLine(alloc.x, lastY, alloc.x + alloc.width, lastY);
}
@Override
protected void paintChild(Graphics g, Rectangle alloc, int index) {
super.paintChild(g, alloc, index);
int lastX = alloc.x + alloc.width;
g.drawLine(alloc.x, alloc.y, lastX, alloc.y);
}
@Override
public View create(Element elem) {
String kind = elem.getName();
if (kind != null) {
if (kind.equals(CodeBugDocument.ELEMENT_TR)) {
return new trView(elem);
} else if (kind.equals(CodeBugDocument.ELEMENT_TD)) {
return new BoxView(elem, View.Y_AXIS);
}
}
// default is to delegate to the normal factory
View p = getParent();
if (p != null) {
ViewFactory f = p.getViewFactory();
if (f != null) {
return f.create(elem);
}
}
return null;
}
public class trView extends TableRow {
public trView(Element elem) {
super(elem);
}
public float getMinimumSpan(int axis) {
return getPreferredSpan(axis);
}
public float getMaximumSpan(int axis) {
return getPreferredSpan(axis);
}
public float getAlignment(int axis) {
return 0f;
}
@Override
protected void paintChild(Graphics g, Rectangle alloc, int index) {
super.paintChild(g, alloc, index);
int lastY = alloc.y + alloc.height - 1;
g.drawLine(alloc.x, alloc.y, alloc.x, lastY);
int lastX = alloc.x + alloc.width;
g.drawLine(lastX, alloc.y, lastX, lastY);
}
};
}
//-------------------------------------------------------------------------------
class CodeBugDocument extends DefaultStyledDocument {
public static final String ELEMENT_TABLE = "table";
public static final String ELEMENT_TR = "table cells row";
public static final String ELEMENT_TD = "table data cell";
public CodeBugDocument() {
putProperty("i18n", Boolean.FALSE);
}
protected void insertTable(int offset, int rowCount, int colCount) {
try {
ArrayList Specs = new ArrayList();
ElementSpec gapTag = new ElementSpec(new SimpleAttributeSet(), ElementSpec.ContentType, "\n".toCharArray(), 0, 1);
Specs.add(gapTag);
SimpleAttributeSet tableAttrs = new SimpleAttributeSet();
tableAttrs.addAttribute(ElementNameAttribute, ELEMENT_TABLE);
ElementSpec tableStart = new ElementSpec(tableAttrs, ElementSpec.StartTagType);
Specs.add(tableStart); //start table tag
fillRowSpecs(Specs, rowCount, colCount);
ElementSpec[] spec = new ElementSpec[Specs.size()];
Specs.toArray(spec);
this.insert(offset, spec);
} catch (BadLocationException ex) {
}
}
protected void fillRowSpecs(ArrayList Specs, int rowCount, int colCount) {
SimpleAttributeSet rowAttrs = new SimpleAttributeSet();
rowAttrs.addAttribute(ElementNameAttribute, ELEMENT_TR);
for (int i = 0; i < rowCount; i++) {
ElementSpec rowStart = new ElementSpec(rowAttrs, ElementSpec.StartTagType);
Specs.add(rowStart);
fillCellSpecs(Specs, colCount);
ElementSpec rowEnd = new ElementSpec(rowAttrs, ElementSpec.EndTagType);
Specs.add(rowEnd);
}
}
protected void fillCellSpecs(ArrayList Specs, int colCount) {
for (int i = 0; i < colCount; i++) {
SimpleAttributeSet cellAttrs = new SimpleAttributeSet();
cellAttrs.addAttribute(ElementNameAttribute, ELEMENT_TD);
ElementSpec cellStart = new ElementSpec(cellAttrs, ElementSpec.StartTagType);
Specs.add(cellStart);
ElementSpec parStart = new ElementSpec(new SimpleAttributeSet(), ElementSpec.StartTagType);
Specs.add(parStart);
ElementSpec parContent = new ElementSpec(new SimpleAttributeSet(), ElementSpec.ContentType, "\n".toCharArray(), 0, 1);
Specs.add(parContent);
ElementSpec parEnd = new ElementSpec(new SimpleAttributeSet(), ElementSpec.EndTagType);
Specs.add(parEnd);
ElementSpec cellEnd = new ElementSpec(cellAttrs, ElementSpec.EndTagType);
Specs.add(cellEnd);
}
}
}
---------- END SOURCE ----------