1

I'm building a custom table cell editor so it adjusts row height during editing. I have this code, but instead of resizing the cell it seams to resize the whole panel, or the frame. When I try to enter a character in a cell the main frame width narrows down to a couple of pixels. Can anyone see the problem?

class MyTableCellEditor extends AbstractCellEditor implements TableCellEditor {

    MyTextpane component = new MyTextpane();
    MyTable table;
    private int row;
    private int col;

    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected,
            int rowIndex, int vColIndex) {

        ((MyTextpane) component).setText((String) value);
        component.addKeyListener(new KeyListener1());
        this.table =(MyTable) table;
        this.row = rowIndex;
        this.col = vColIndex;
        return component;
    }

    public Object getCellEditorValue() {
        return ((MyTextpane) component).getText();
    }

    public class KeyListener1 implements KeyListener {

        @Override
        public void keyTyped(KeyEvent ke) {
        }

        @Override
        public void keyPressed(KeyEvent ke) {
        }

        @Override
        public void keyReleased(KeyEvent ke) {
            adjustRowHeight(table, row, col);
        }
        private java.util.List<java.util.List<Integer>> rowColHeight = new ArrayList<java.util.List<Integer>>();
        private void adjustRowHeight(JTable table, int row, int column) {
        //The trick to get this to work properly is to set the width of the column to the
        //textarea. The reason for this is that getPreferredSize(), without a width tries
        //to place all the text in one line. By setting the size with the with of the column,
        //getPreferredSize() returnes the proper height which the row should have in
        //order to make room for the text.
        int cWidth = table.getTableHeader().getColumnModel().getColumn(column).getWidth();
        setSize(new Dimension(cWidth, 1000));
        int prefH = getPreferredSize().height;
        while (rowColHeight.size() <= row) {
            rowColHeight.add(new ArrayList<Integer>(column));
        }
        java.util.List<Integer> colHeights = rowColHeight.get(row);
        while (colHeights.size() <= column) {
            colHeights.add(0);
        }
        colHeights.set(column, prefH);
        int maxH = prefH;
        for (Integer colHeight : colHeights) {
            if (colHeight > maxH) {
                maxH = colHeight;
            }
        }
        if (table.getRowHeight(row) != maxH) {
            table.setRowHeight(row, maxH);
        }
    }

    }
}
Igor
  • 1,532
  • 4
  • 23
  • 44
  • 1
    For better help sooner, post an [SSCCE](http://sscce.org/). – Andrew Thompson Oct 15 '12 at 11:06
  • only DocumentListener can to force Document, PlainDocument to returns coordinates, KeyListener is contraproductive, simple useless, in the case that you want ot filtering of un_:wanted chars put there DocumentFilter instead of DocumentListener and override notifications to the Document :-) – mKorbel Oct 15 '12 at 12:53
  • hmm .. can't reproduce any narrowing up in the container hierarchy (using your editor with a JTextArea instead of a JTextPane, out of lazyness: to match a custom renderer). But even so the behaviour is far from optimal, as the editor's size changes unpredictably while typing. Actually, I doubt that dynamically changing the row height while typing can be achieved without heavy tweaking. – kleopatra Oct 15 '12 at 14:31
  • There must be an error in adjustRowHeight(). I can't see why else this would happen. – Igor Oct 15 '12 at 14:38
  • _must be an error in adjustRowHeight()_ didn't look at that, but now that you mention it ... wth are you doing there? Simply loop across the columns and use Math.max to decide whether or not you need to increase the height. – kleopatra Oct 15 '12 at 14:43
  • @kleopatra I'm not sure. All I know is it sets table's row height. I'm also not sure if those loops are really needed. How can I use Math.max instead? – Igor Oct 15 '12 at 15:04
  • How comes that you show us code you don't understand? Copied... ? Anyway, it's simple logic, in the easiest case - if you only want to ensure that the height increases if needed - not even looping required: compare the current pref against the actual rowHeight. – kleopatra Oct 15 '12 at 15:13

2 Answers2

1

have look at

  • my answer about doLayout(could be fired from CellEditor)

  • or (more than confortable way to use TextUtils) comment by @kleopatra about getPreferredSize

  • this could (very) confusing the users,

  • because I miss JScrollPane, there have to override MaxSize, max size is height & weight for JScrollPane, otherwise part of CellEditor can going outside of screeens bounds .........,

  • don't do that, put there JScrollPane with JTextComponents, override PreferredSize for CellEditor,


everything are wrong, my view,

  • create applications modal popup window (based only on JDialog, becasue JWindow doesn't alloved input to the JTextComponent) with JTextComponent, implements there KeyBindings for ESC key, the same for lost Fucus for JDialog, then could be undecorated without any issue

put there Save JButton

  • output from Save Button reditect to the selected cell, you can't lost focus from application modal inside JTable

  • contents should be formatted, filtered, modified one JDialog for all cells from JTable

Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • You are overriding the Renderer. I need to override the Editor so when I edit a cell I can increase row size by pressing Enter or just by pasting a long text. I need cell text to be wraped during edit. – Igor Oct 15 '12 at 13:43
  • 1
    I really don't understand what your previous comments means. You can't see any difference between Renderer and Editor? – Igor Oct 15 '12 at 13:54
  • yes, btw add there DocumentFilter/Listener instead of KeyListener and override a new line for built_in KeyBindings, [I'll search for reference ....](http://tips4java.wordpress.com/2008/10/10/key-bindings/) – mKorbel Oct 15 '12 at 14:02
  • Well there is a difference and it's in the point where adjustRowHeight() function is called. In the renderer I call this method in getTableCellRendereComponent() and it works fine. I can't call it in the same method in the Editor because it won't adjust the height as you type. – Igor Oct 15 '12 at 14:02
  • aaach MyTextpane theoretical discusion, nobody can to see that, can you demonstrating that with Popup, ToolTip or JDialog, there are two ways pack() for all HeavyWeight containers or getView (returns Insets) from JTextComponents – mKorbel Oct 15 '12 at 14:07
  • @Igor _call this method in getTableCellRendereComponent()_ **Dont** - you _must not_ change the table state in the renderer. – kleopatra Oct 15 '12 at 14:50
  • @kleopatra I already do call the adjustRowHeight() method in getTableCellRendererComponent() and it resizes fine after focus is lost. But I want to be able to resize cell during edit, so I figured I need to call this method on keyReleased. But, unfotunately i resizes the whole frame. No idea why. – Igor Oct 15 '12 at 14:59
  • @Igor - I understand that ;-) But what you are doing in the renderer is **WRONG** even if it appears to be working. – kleopatra Oct 15 '12 at 15:10
  • @kleopatra Maybe it's got something to do with the fact that the renderer extends JTextPane, while the Editor extends AbstractCellEditor? – Igor Oct 15 '12 at 15:34
1

As an alternative to resizing the row while editing, consider TablePopupEditor, which uses JTextArea.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045