I need to create a JTable inside JScrollPane with resizeable columns (when user increase column width - horizontal scrollbar appears).
For this I have use table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
.
Also, when viewport is wide enough to contain entire table - columns should stretch to fill viewport width.
To accomplish this I have override getScrollableTracksViewportWidth()
method of JTable class as follow:
@Override
public boolean getScrollableTracksViewportWidth() {
return getPreferredSize().width < getParent().getWidth();
}
This approach works good, except one thing: when I first time try to resize column it return own width to start position. If I quickly resize column and release mouse table continue to work good.
So, what is the reason of such behavior? Why table try to resize even if getScrollableTracksViewportWidth()
returns false? Or, maybe, you can propose better solution for implementing such resize mode?
Bellow is a simple working example of above problem:
import javax.swing.*;
public class TestTable {
private static Object[][] data = new Object[][] {
{ "a", "b", "c" },
{ "d", "e", "f" }
};
private static Object[] colNames = new Object[] { "1", "2", "3" };
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JTable table = new JTable(data, colNames) {
@Override
public boolean getScrollableTracksViewportWidth() {
return getPreferredSize().width < getParent().getWidth();
}
};
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(table));
frame.pack();
frame.setVisible(true);
}
});
}
}
Right-click on the table cells. From popup menu, choose "Table Contents..". Uncheck the editable check box for the column you want to make it non-editable.
The TableModel interface specifies the methods the JTable will use to interrogate a tabular data model. The JTable can be set up to display any data model which implements the TableModel interface with a couple of lines of code: TableModel myData = new MyTableModel(); JTable table = new JTable(myData);
The JTable is used to display and edit regular two-dimensional tables of cells. See How to Use Tables in The Java Tutorial for task-oriented documentation and examples of using JTable .
It seemed like the default doLayout()
logic wasn't working when you tried to increase the size of a column when the horizontal scrollbar wasn't visible, so I got rid of the default logic and just accepted the width of the column without attempting to adjust it.
import javax.swing.*;
import javax.swing.table.*;
public class TestTable {
private static Object[][] data = new Object[][] {
{ "a", "b", "c" },
{ "d", "e", "f" }
};
private static Object[] colNames = new Object[] { "1", "2", "3" };
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JTable table = new JTable(data, colNames)
{
@Override
public boolean getScrollableTracksViewportWidth()
{
return getPreferredSize().width < getParent().getWidth();
}
@Override
public void doLayout()
{
TableColumn resizingColumn = null;
if (tableHeader != null)
resizingColumn = tableHeader.getResizingColumn();
// Viewport size changed. May need to increase columns widths
if (resizingColumn == null)
{
setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
super.doLayout();
}
// Specific column resized. Reset preferred widths
else
{
TableColumnModel tcm = getColumnModel();
for (int i = 0; i < tcm.getColumnCount(); i++)
{
TableColumn tc = tcm.getColumn(i);
tc.setPreferredWidth( tc.getWidth() );
}
// Columns don't fill the viewport, invoke default layout
if (tcm.getTotalColumnWidth() < getParent().getWidth())
setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
super.doLayout();
}
setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
}
};
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(table));
frame.pack();
frame.setVisible(true);
}
});
}
}
Edited to use AUTO_RESIZE_ALL_COLUMNS.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With