JDK-7072926 : Swing Table Layout Update
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 6u26
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2011-07-29
  • Updated: 2012-09-06
  • Resolved: 2012-05-23
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
JDK 1.6_26

ADDITIONAL OS VERSION INFORMATION :
Mandriva Linux 2010


A DESCRIPTION OF THE PROBLEM :
A swing table is update on his majour axis but it is not update on his minor axis when we remove texte.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Launch the code.
1-Insert a texte after "Cell11" and remove the texte.
-Put the curso before "TextB" and press "Enter".
2-Put the curso after "Cell11" and press "Enter" to insert a new line in the cell. Remove this new line.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Launch the code.
When we Insert a texte after "Cell11" or ... or "Cell43", the table layout is update. and when we remove the texte, the table layout is update too.
ACTUAL -
Launch the code.
1-Insert a texte after "Cell11", the table layout is update.
-Remove the texte, the table layout is not update
-Put the curso before "TextB" and press "Enter", the table layout is update.
2-Put the curso after "Cell11" and press "Enter" to insert a new line in the cell. The table layout is update remove this new line, the table layout is also update.

Conclusion : This problem occurs only when removing along the minor axis.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.text.*;
//-------------------------------------------------------------------------------

public class Application extends JFrame {

    JEditorPane edit = new JEditorPane();

    public Application() {
        super("Tables in JEditorPane example");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        edit.setEditorKit(new TableEditorKit());
        initTableDemo();

        this.getContentPane().add(new JScrollPane(edit));
        this.setSize(300, 200);
        this.setLocationRelativeTo(null);

    }

    private void initTableDemo() {
        TableDocument doc = (TableDocument) edit.getDocument();
        try {
            doc.insertString(0, "TextB ", null);
        } catch (BadLocationException ex) {
        }
        doc.insertTable(7, 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) {
        Application m = new Application();
        m.setVisible(true);
    }
}
//-------------------------------------------------------------------------------

class TableEditorKit extends StyledEditorKit {

    ViewFactory defaultFactory = new TableFactory();

    public ViewFactory getViewFactory() {
        return defaultFactory;
    }

    public Document createDefaultDocument() {
        return new TableDocument();
    }
}
//-------------------------------------------------------------------------------

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(TableDocument.ELEMENT_TABLE)) {
                return new tableView(elem, this);
            } else if (kind.equals(TableDocument.ELEMENT_DATA)) {
                return new BoxView(elem, View.Y_AXIS);
            } else if (kind.equals(StyleConstants.IconElementName)) {
                return new IconView(elem);
            }

        }
        // default to text display
        return new LabelView(elem);

    }
}
//-------------------------------------------------------------------------------
class tableView extends TableView implements ViewFactory {

    ViewFactory vf;

    public tableView(Element elem, ViewFactory vf) {
        super(elem);
        this.vf = vf;
    }

    public ViewFactory getViewFactory() {
        return this;
    }

    public float getMaximumSpan(int axis) {
        return getPreferredSpan(axis);
    }

    public float getAlignment(int axis) {
        return 0.5f;
    }

    protected void paintChild(Graphics g, Rectangle alloc, int index) {
        super.paintChild(g, alloc, index);
        g.setColor(Color.black);
        g.drawLine(alloc.x, alloc.y, alloc.x + alloc.width, alloc.y);
        int lastY = alloc.y + alloc.height;
        g.drawLine(alloc.x, lastY - 1, alloc.x + alloc.width, lastY - 1);
    }

    public View create(Element elem) {
        String kind = elem.getName();
        if (kind != null) {
            if (kind.equals(TableDocument.ELEMENT_ROW)) {
                return new trView(elem);
            }
        }
        return vf.create(elem);
    }

    public class trView extends TableRow {

        public trView(Element elem) {
            super(elem);
        }

        @Override
        public int getResizeWeight(int axis) {
            return 0;
        }

        @Override
        protected void paintChild(Graphics g, Rectangle alloc, int index) {
            super.paintChild(g, alloc, index);
            g.setColor(Color.gray);
            g.drawLine(alloc.x, alloc.y, alloc.x, alloc.y + alloc.height);
            g.drawLine(alloc.x + alloc.width, alloc.y, alloc.x + alloc.width, alloc.y + alloc.height);
        }
    };
}

//-------------------------------------------------------------------------------
class TableDocument extends DefaultStyledDocument {

    public static final String ELEMENT_TABLE = "table";
    public static final String ELEMENT_ROW = "row";
    public static final String ELEMENT_DATA = "data";

    public TableDocument() {
    }

    protected void insertTable(int offset, int rowCount, int colCount) {
        try {
            ArrayList Specs = new ArrayList();

            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) {
            ex.printStackTrace();
        }
    }

    protected void fillRowSpecs(ArrayList Specs, int rowCount, int colCount) {
        SimpleAttributeSet rowAttrs = new SimpleAttributeSet();
        rowAttrs.addAttribute(ElementNameAttribute, ELEMENT_ROW);
        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_DATA);

            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 ----------