Search code examples
javaswingjtablerowheader

JTable- Resize row header when row is resized


I have a grid (JTable) that looks like MS Excel's grid. I want to allow the user to resize rows and columns. For the columns I simply used this :

grid.getTableHeader().setResizingAllowed(true);

And for the rows I took the TableRowResizer class from here and which I'm using like this :

new TableRowResizer(grid);

This works fine. However, I've one problem : when resizing a row the row header is not resized too.

enter image description here

Here's how I made the row headers :

    AbstractListModel lm = null;
    lm = new TableListModel(grid);
    final JList list = new JList(lm);
    list.setFixedCellWidth(60);         
    list.setFixedCellHeight(grid.getRowHeight());
    list.setCellRenderer(new TableRowHeaderRenderer(grid));
    list.setBackground(grid.getTableHeader().getBackground());
    scrollPane.setRowHeaderView(list);

Here's the TableRowHeaderRenderer class :

    class TableRowHeaderRenderer extends JLabel implements ListCellRenderer {   

        private JTable table;

        public TableRowHeaderRenderer(JTable table)
        {
            this.table = table;
            JTableHeader header = table.getTableHeader();
            setOpaque(true);
            setBorder(BorderFactory.createEtchedBorder());
            setHorizontalAlignment(CENTER);
            setForeground(header.getForeground());
            setBackground(header.getBackground());
            setFont(header.getFont());
        }

        public Component getListCellRendererComponent(JList list, 
        Object value, int index, boolean isSelected, boolean cellHasFocus) 
        {
            Color bg = UIManager.getColor("TableHeader.background");
            int selectedrow =  table.getSelectedRow();
            if (selectedrow==index) bg = new Color(107, 142, 35);
            setBackground(bg);
            setText("" + Grid.getRowName(index));
            return this;
        }
        }

And this is the TableListModelclass :

    class TableListModel extends AbstractListModel{
        private JTable mytable;

        public TableListModel(JTable table) {
            super();
            mytable = table;
            }

        public int getSize() {
            return mytable.getRowCount();
            }

        public Object getElementAt(int index) {
            return "" + index;
            }
        }

Solution

  • Check out the Row Number Table. It uses a JTable (instead of a JList) to render the row numbers. Therefore you can keep the row heights in sync with the main table.

    However, I can't get the row header to repaint automatically when the row height of the main table is changed since no event is fired when an individual row height is changed. So you will also need to modify the resizing code to look something like:

    table.setRowHeight(resizingRow, newHeight);
    JScrollPane scrollPane = (JScrollPane)SwingUtilities.getAncestorOfClass(JScrollPane.class, table);
    scrollPane.getRowHeader().repaint();