Any direction someone could point me in for auto-sizing only the last (right-most) column in a jtable? I want the user to be able to set the size of columns and be allowed to set them beyond the scrollable viewing area, but if the viewing area is wider than the column widths, then the last column would be auto-sized to fit the empty space.

Recommended Answers

All 10 Replies

I figured it was something simple, just needed to pull my eyes from the screen for a bit. I made the right-most column an empty dummy column that basically just fills the empty space when a view is wider than the table being displayed.

JScrollPane libraryScrollPane = new JScrollPane(libraryTable);

libraryScrollPane.addComponentListener(new ComponentAdapter()
        {
            public void componentResized(ComponentEvent e)
            {
                Component c = e.getComponent();
                int viewWidth = c.getWidth();                
                TableColumn tc = libraryTable.getColumnModel().getColumn(libraryTableModel.getColumnCount()-1);
                int tableWidth = libraryTable.getWidth() - tc.getWidth();
                int diffWidth = viewWidth - tableWidth;
                
                if (diffWidth > 0)
                {
                    tc.setPreferredWidth(diffWidth);
                }
            }
        });

I've tried almost the same code to control the dummy column's width when the user resizes a column, but the width of resizing column jumps all around the place.

I swear I looked at all the constants, now I feel like an idiot. Will that still allow the table width to be greater than the view?

No, sorry, it won't. I should have checked it before suggesting.

Try this

Component c = evt.getComponent();
int viewWidth = c.getWidth();
int tableWidth = libraryTable.getWidth();
int diffWidth = viewWidth - tableWidth;

if (diffWidth > 0) {
    TableColumn tc = libraryTable.getColumnModel().getColumn(libraryTable.getColumnCount()-1);
    tc.setPreferredWidth(tc.getWidth() + diffWidth - 3);
}

The magic number 3 is just there to keep it from being just a tiny bit wider than the internal display area and forcing an unnecessary scroll bar (I didn't spend the time to find out which component width was causing it - probably just a border or inset on one of them).

That does still allow them to manually make the last column narrower than the scroll pane. If you really want to avoid that you would need to call this when a column is resized as well.

I have that part working ok, also noticed the issue which needed the 'magic number' as well. The problem I'm having is that for whatever reason, calling this when a column is manually resized doesn't always work. I'm not sure if it's because when I resize a column the method resizes the last column which in turn calls the listener again. Is there a way to detect which column was resized triggering the event?

Not from the ChangeEvent supplied by columnMarginChanged() unfortunately. In most case, the resize affects more than one column at the same time, so it's up to you to handle a particular column on your own. I fiddled with a few things but didn't come up with a clean way of avoiding that circular cascade in the resizing and still have it resize to fill the pane after they are done trying to make it smaller. That's to be expected though since they are actually fighting against the listeners with the mouse to drag it smaller and the code is just trying to respond the way you want it to.

This change

if (diffWidth > 0) {
    int newWidth = tc.getWidth() + diffWidth - 3;
    tc.setPreferredWidth(newWidth);
    tc.setMinWidth(newWidth);
}

does prevent them from making it too small to fill the pane, but if the min size gets larger from a panel resize, it can't be set back to a smaller size later. It becomes a one way street in that respect.

A relevant question might be though, if the user intentionally makes that column narrower and it doesn't fill the pane, should you care enough to prevent it?

not really, but its nice to keep the look clean and uniform.

Though it doesn't support what I was trying to accomplish in this thread, it does support several other features that I had planned on implementing anyway.

Glazed Lists

Looked pretty handy and thought it was worth sharing with those who haven't heard of this project before.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.