Question

private float[] cwidth = { 0.1f, 0.3f, 0.3f, 0.2f, 0.1f };

setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

for (int i = 0; i < cwidth.length; i++) {
            getColumnModel().getColumn(i).setPreferredWidth((int) (getPreferredScrollableViewportSize().width * cwidth[i]));
        }

I have the following problem:

I have a JTable with 5 columns. The first is a 3 digit number, the second a string, then a JProgressBar, another string and a button.

Now i want them to have width depending on the size of the Table. Above you can see my actual attempt, but that doesn't work.

I already searched the web, but all i found didn't help me, because it always was about setting size to a non dynamically size.

I hope you can help me.

Thanks for the Help. I love this side !!

Here my solution:

for (int i = 0; i < cwidth.length; i++) {
            getColumnModel().getColumn(i).setPreferredWidth((int) (600 * cwidth[i]));
            getColumnModel().getColumn(i).setMinWidth((int) (100 * cwidth[i]));
            getColumnModel().getColumn(i).setMaxWidth((int) (1000 * cwidth[i]));
        }
Was it helpful?

Solution

it's not trivial to interfere with a table's internal column layout (basically, it is its own LayoutManager with the columns as "children"). On the bright side: the default behaviour isn't that bad, it already has a reasonable resizing modes. The default resizeAll most probably does what you want with just a little config needed - which isn't overly intuitve :-)

To start with, read the api doc of JTable.doLayout() - it describes the exact behaviour. The most important point is to understand how excess width is distributed across columns:

deltaI = (excess) * ((maxI - prefI) / (maxAll - prefAll)) 

(with postFix I denoting the individual column and All the sum of the individual values, respectively), that is factor of individual difference of max/pref to sum of max/pref. Looks like a reasonable decision, just ... with default max being Integer.MAX, that factor is about the same for all columns, irrespective of their prefWidht. That's basically, why the resizing appears so unintuitive and why you need to adjust the maxSize (as @Lajos Arpad already pointed out :-) to get a reasonable default resizing behaviour.

So instead of trying to do-it-yourself (which isn't a good idea, as always with LayoutManagers), configure the column properties as needed:

// start out with a reasonable pref size, f.i. from a prototype or 
// measuring the actual cell content (both supported by JXTable)
forEachColumn
    column.setPreferredWidth(....);

// then configure the maxWidth proportionally 
private float[] cwidth = { 0.1f, 0.3f, 0.3f, 0.2f, 0.1f };
forEachColumn
    int max = ((int) (1000f * cwidth[columnExt.getModelIndex()]));
    columnExt.setMaxWidth(max);

Note that the 1000 is an arbitrary magic number, you probably want to play a bit with it, it depends on screen resolution and user expectation

OTHER TIPS

If the preferred width is smaller than the minimal width or bigger than the maximum width then your column won't be resized by the preferred width. You should also control the minimal width and maximal width too to guarantee that your preferred width is between them.

Also, by default the columns are automatically resized by the table size change, you should check the auto resize mode too.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top