1

Is there any mechanism to make a JTable's cells perfectly square? Currently I'm just overriding this method in the table's implementation:

@Override
public int getRowHeight() {
    return this.getColumnModel().getColumn(0).getWidth();
}

This works in most cases like in the image below where I have a 15x15 JTable:

enter image description here

But if I extend the JPanel the table sits on width wise the cell's continue to expand width and length wise resulting in the lower 3 rows being cut off:

enter image description here

I am wondering if there is a better solution to have a JTable's cells be perfectly square?

219CID
  • 340
  • 5
  • 15
  • when a resize happens, make sure you use the lesser of the two sizes (Width and Height) to define the cell sizes? – sorifiend Aug 12 '20 at 14:14
  • So additionally override getRowHeight? Just want to make sure I’m understanding correctly – 219CID Aug 12 '20 at 16:03
  • @sorifiend I tried doing this and ended up with something like this: return Math.min(super.rowHeight, this.getColumnModel().getColumn(0).getWidth()); – 219CID Aug 13 '20 at 01:40
  • I was more meaning that you either need to capture the resize event, or take the window size size into account, and then use some logic to work out if the width or height is smaller (The limiting factor). Then based on which is smaller you can change the size of the cells. For example if the height was smaller you would need to do `cellSize = windowHight / cellsCount`, or if the width was smaller you would do `cellSize = windowWidth / cellsCount` – sorifiend Aug 13 '20 at 02:03

1 Answers1

1

Further on my comment, you would need to use some logic to work out if the width or height is smaller (The limiting factor). Then based on which is smaller you can change the size of the cells.

Rather than using an override on the row height and trying to mess with column overrides, I instead reccomend intercepting the JTable componentResized event and simply set the sizes we want. I have assumed a fixed number of cells (15x15) for this example:

int rowCount = 15;
int colCount = 15;

your_JTable.addComponentListener(new ComponentAdapter(){

    @Override
    public void componentResized(ComponentEvent e){
        //Get new JTable component size
        Dimension size = getSize();
        
        int cellSize;

        //Check if height or width is the limiting factor and set cell size accordingly
        if (size.height / rowCount > size.width / colCount){
            cellSize = size.width / colCount;
        }
        else{
            cellSize = size.height / rowCount;
        }
        
        //Set new row height to our new size
        setRowHeight(cellSize);
        
        //Set new column width to our new size
        for (int i = 0; i < getColumnCount(); i++){
            getColumnModel().getColumn(i).setMaxWidth(cellSize);
        }
    }
});

This provides perfectly square cells in JDK13 when resized both horizontally or vertically or both. I realise that I answered your previous question as well, so here is a working example using that code:

enter image description here

sorifiend
  • 5,927
  • 1
  • 28
  • 45
  • 1
    This works great. Two things to consider. First, if you make the table incredibly small there can be an error thrown that "New row height less than 1", this is a very easy fix by just ensuring cellSize is always greater than 1. Secondly, if you don't have rows/columns as a class attribute is it alright to just call getRowCount() and getColCount()? – 219CID Aug 14 '20 at 03:04
  • 1
    @219CID Good spotting on the minimum size. And yes, you should have no issues with `getRowCount()` and `getColCount()` provided that no new rows/columns are added during the resize event. – sorifiend Aug 14 '20 at 03:19