Reputation: 53
I have a JTable
with 5 Columns specified in a TableColumnModel. I want the table to use all available horizontal space in the panel (which can vary), but I want to limit the resizing to the last three rows.
In more detail:
The first two columns are initialized with a preferred width, however the user should be able to resize the column manually by dragging with the mouse.
The last three columns should divide equally all the remaining space that isn't being used by the first two columns. EDIT: They also need to be resizable manually.
I've tried the following:
Setting the table to autoResizeMode JTable.AUTO_RESIZE_ALL_COLUMNS
. This suceeded in
using up all available space, but (obviously) it also resized the first two columns.
I've reacted to this by setting a min and max for the first two columns. That worked,
but it violated my constraint of having them resizable manually.
Is there a simple way in the JTable
-API to achieve this?
Thanks in advance!
Upvotes: 0
Views: 3803
Reputation: 51524
As Thomas already answered, there is no simple api to achieve what you want: you have to implement the behaviour yourself. That might not be trivial in a general context, but manageable in your concrete context. Just to ensure I do understand your requirement correctly:
A) 2 columns are resizable by the user, 3 columns are not resizable by the user (they should have the same width)
B) while the user resizes one of the 2 resizable columns, the other resizable columns should keep its current width, any space distribution should effect the 3 not-resizable columns only, evenly distributing the excess/missing width across them.
Basically, the trick is to "fix" the size of the other resizable columns while resizing one of them. The "fix" is achieved by setting both its min/max to its preferred. Then the even distribution of space across the remaining columns will happen automatically in AUTO_RESIZE_ALL_COLUMNS mode. The problem is to detect the resizing start/stop: JTableHeader has a property resizingColumn which unfortunately is unbound (aka: doesn't fire on change) in core. SwingX, on the other hand, (you already guessed I would come to mention SwingX sooner or later :-) promoted that property to a full-fledged bean property - so simply listen and update the min/max size constraints as appropriate. Here's a code snippet using SwingX
// custom ColumnFactory to configure the columns
ColumnFactory factory = new ColumnFactory(){
/**
* @inherited <p>
*/
@Override
public void configureTableColumn(TableModel model,
TableColumnExt columnExt) {
super.configureTableColumn(model, columnExt);
columnExt.setResizable(columnExt.getModelIndex() < 2);
if (columnExt.getModelIndex() >= 2) {
columnExt.setPreferredWidth(50);
} else {
columnExt.setPreferredWidth(150);
}
}
/**
* @inherited <p>
* Overridden to do nothing
*/
@Override
public void configureColumnWidths(JXTable table,
TableColumnExt columnExt) {
}
};
final JXTable table = new JXTable();
table.setColumnFactory(factory);
table.setModel(new DefaultTableModel(20, 5));
// propertyChangeListener
PropertyChangeListener l = new PropertyChangeListener() {
TableColumn first = table.getColumn(0);
TableColumn second = table.getColumn(1);
@Override
public void propertyChange(PropertyChangeEvent evt) {
TableColumn resizingColumn = (TableColumn) evt.getNewValue();
if (resizingColumn == null) {
TableColumn oldResizing = (TableColumn) evt.getOldValue();
TableColumn other = oldResizing == first ? second : first;
other.setMaxWidth(Integer.MAX_VALUE);
other.setMinWidth(15);
} else {
TableColumn other = resizingColumn == first ? second : first;
other.setMaxWidth(other.getPreferredWidth());
other.setMinWidth(other.getPreferredWidth());
}
}
};
table.getTableHeader().addPropertyChangeListener("resizingColumn", l);
This is SwingX for lazyness - easy enough to implement yourself:
a) configure the tableColumns manually
b) subclass JTableHeader and implement setResizingColumn to fire on change
c) subclass JTable and implement createTableHeader to return the subclassed header
Enjoy! Jeanette
Upvotes: 1
Reputation: 88707
AFAIK there's no way to exclude the columns from autoresizing. Setting a min/max size affects the size calculation but from the JTable source it seems that you can't exclude columns.
When JTable.AUTO_RESIZE_ALL_COLUMNS
is used, the range of columns to be resized can't be restricted. Thus, the table model is called to set the column width for each column and there constraints are applied. However, I don't see any way the table model can distinguish between automatic and manual resize.
Upvotes: 0