JTable, SelfResizingTable

A JTable is used to display and edit regular two-dimensional tables of cells. The TableModel encapsulates a table's data and (together with the TableColumnModel) controls the representation of the data.
A customized SelfResizingTable  Example 25

RADi allows you to customize tables to some degree. You can define TableCellRenderers which provide the view of the data on a per column basis. A RADi-special kind of JTable is SelfResizingTable which calculates columns' preferred size before the table is displayed.
JTable and SelfResizingTable displaying identical data (both tables are 300 px. wide)

Note: SelfResizingTable isn't for free. It costs time to calculate column widths because every table cell is inspected for its preferred width. I used SelfResizingTable with table models containing up to 100,000 rows and found performance acceptable.
If you feed a SelfResizingTable with a table model of your own, you need to know that every TableModel method starting with fire finally will call tableChanged(TableModelEvent) and so trigger recalculation of column widths.


Feed a table with your own data

Of course you can use JTable (or SelfResizingTable) as is and program your own table model and renderers.
You can also define a table model using RADi's TableModel editor, it allows you to sketch a table's appearance rather precisely. But be aware that all renderers will disappear as soon as you set another table model or column model on the table. You can feed a RADi-defined table with your own data, as long as you don't (directly or indirectly) change its column model.
The following code examples will preserve renderers:
// define some dummy data
Object[][] data = new Object[][] {
    {"01", "02", "03", "04", "05", "06"},
    {"07", "08", "09", "10", "11", "12"},
    {"13", "14", "15", "16", "17", "18"},
    {"19", "20", "21", "22", "23", "24"},
    {"25", "26", "27", "28", "29", "30"},
    {"31", "32", "33", "34", "35", "36"}
};

// fill the table
for(int i = 0; i < data.length; i++) {
    for(int j = 0; j < data[i].length; j++) {
        table.setValueAt(data[i][j], i, j);
    }
}

// insert a record (insert position must be <= rowCount)
((DefaultTableModel)table.getModel()).insertRow(6, data[2]);

// remove a record
((DefaultTableModel)table.getModel()).removeRow(2);

// move a record (new position must be < rowCount)
((DefaultTableModel)table.getModel()).moveRow(1, 1, 6);

// add a record to the end of the table
((DefaultTableModel)table.getModel()).addRow(
    new Object[] {"T", "h", "e", "E", "n", "d"}
);

// change the number of rows
((DefaultTableModel)table.getModel()).setRowCount(10);

The following code examples will remove renderers:
// add a new column
((DefaultTableModel)table.getModel()).addColumn("New");

// change the number of columns
((DefaultTableModel)table.getModel()).setColumnCount(8);

// set column names
((DefaultTableModel)table.getModel()).setColumnIdentifiers(
    new Object[] {"-A-", "-B-", "-C-", "-D-", "-E-", "-F-"});

// set a new data vector
((DefaultTableModel)table.getModel()).setDataVector(data,
    new Object[] {"-A-", "-B-", "-C-", "-D-", "-E-", "-F-"});

// set a new table model
table.setModel(new DataModel());