I am trying to get the sorted TableModel of a JTable which is done by the following simple regex criteria:
try {
TableRowSorter<TableModel> sortRow = new TableRowSorter<>(testTable.getModel());
testTable.setRowSorter(sortRow);
String sortString = "Something";
sortRow.setRowFilter(RowFilter.regexFilter("(?i)" + sortString));
}
which will sort the data according to sortString.
But when I try to do the following :
try {
TableRowSorter<TableModel> sortRow = new TableRowSorter<>(testTable.getModel());
// ....
// previous code
// ....
TableModel tM = testTable.getModel();
someOtherTestTable.setModel(tM); //<---Here
}
It provides me the DefaultTableModel. So, my question is this: How do I get the sorted TableModel so that I can post to another JTable?
A TableRowSorter conditions the view, JTable; the model, TableModel, remains unchanged. If the underlying model of the RowSorter remains the same, you should be able apply the old TableRowSorter to the new JTable using setRowSorter().
…
someOtherTestTable.setModel(tM);
someOtherTestTable.setRowSorter(sortRow);
Related
I have two JTables which share a TableModel.
This is so that I can set them up in a scroll pane such that one of them has a few columns showing on the left and does not scroll sideways, visually 'freezing' those columns, and the other contains the rest of the columns.
They are always sorted the same so that the rows match up. This is done using a RowSorter listener, shown below. (frozenTable and tableView are the names of my JTables).
RowSorterListener rowSorterListener = new RowSorterListener() {
#Override
public void sorterChanged(RowSorterEvent e) {
if (RowSorterEvent.Type.SORT_ORDER_CHANGED == e.getType()) {
RowSorter source = e.getSource();
if (source == tableView.getRowSorter()) {
frozenTable.getRowSorter().removeRowSorterListener(this);
frozenTable.getRowSorter().setSortKeys(source.getSortKeys());
frozenTable.getRowSorter().addRowSorterListener(this);
} else {
tableView.getRowSorter().removeRowSorterListener(this);
tableView.getRowSorter().setSortKeys(source.getSortKeys());
tableView.getRowSorter().addRowSorterListener(this);
}
}
}
};
At another point in my code, I want to be able to get the TableColumn objects that are currently being sorted on. Before I added the frozentable, I was able to do this with the following code:
List<? extends SortKey> sortKeys = tableView.getRowSorter().getSortKeys();
for(SortKey key : sortKeys){
TableColumn column = tableView.getColumnModel().getColumn(key.getColumn());
// other stuff in the loop
}
It seems as though a SortKey only has two things in it, a column index and a SortOrder. This raises two questions:
How is my RowSorterListener even managing to sort the tables based on columns from one or the other table? If all I'm passing when I say 'setSortKeys' is 'sort by column 3' and column 3 is different for each JTable, then how is this working in the first place? Because it does work. If I have a Name column in the frozenTable and an Age column in the tableView and I sort by Age, it does sort both JTables by the Age column.
How do I get the TableColumn object associated with a SortKey?
Check out the Fixed Column Table which is a reusable class that allows you to share a model between two tables
The code to create the fixed column table is:
JTable table = new JTable(...);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
JScrollPane scrollPane= new JScrollPane( table );
FixedColumnTable fct = new FixedColumnTable(2, scrollPane);
JTable fixed = fct.getFixedTable();
I don't think you need the sorter listener.
You should just be able to share the RowSorter using code something like:
table.setAutoCreateRowSorter(true);
fixed.setRowSorter(table.getRowSorter());
table.setUpdateSelectionOnSort(true);
fixed.setUpdateSelectionOnSort(false);
My JTable is declared as so:
String[] cols = {"Name","Location"};
String[][] data = new String[][] {{"Name","Location"}};
JTable table = new JTable(data, cols);
So i came across a problem when trying to update my JTable's data... I'm suppose to be adding a new row to the table. Here is my code for that:
data = new String[][] {{"Name","Location"}{"Name1","Location1"}};
DefaultTableModel dm = (DefaultTableModel)(table.getModel());
dm.fireTableDataChanged();
For some reason i get an error on the Line:
DefaultTableModel dm = (DefaultTableModel)(table.getModel());
The error shown is...
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: javax.swing.JTable$1 cannot be cast to javax.swing.table.DefaultTableModel
at client.pages.ClientPage.update(ClientPage.java:171)
Line 171 of my ClientPage.java is the above line of code that i said the error is on.
Anyone know why its doing this?
table.getModel(); //Suppose to return TabelModel not JTable
table.getModel() isn't returning a JTable, it's returning an anonymous class in JTable that extends TableModel. Therefore, table.getModel() is indeed returning the correct class type.
The error occurs, however, because you try to cast this anonymous table model to DefaultTableModel, which is another subclass of TableModel, but is not the type being returned by table.getModel().
To fix this, simply treat the table model as the interface type TableModel; don't assume it's a DefaultTableModel.
Start by taking a look at How to Use Tables and the JavaDocs for DefaultTabelModel
You should change the way you are creating the table and model to something more like...
String[] cols = {"Name","Location"};
String[][] data = new String[][] {{"Name","Location"}};
JTable table = new JTable(new DefaultTableModel(date, cols));
JTable(Object[][], Object[]) actually uses it's own implementation of a the TableModel
Next, change....
data = new String[][] {{"Name","Location"}{"Name1","Location1"}};
DefaultTableModel dm = (DefaultTableModel)(table.getModel());
dm.fireTableDataChanged();
to something more like...
data = new String[][] {{"Name","Location"}{"Name1","Location1"}};
DefaultTableModel dm = (DefaultTableModel)(table.getModel());
dm.fireTableDataChanged();
to something more like...
data = new String[] {"Name1","Location1"};
DefaultTableModel dm = (DefaultTableModel)(table.getModel());
dm.addRow(data);
I have a JTable defined in this way:
public JTable table_1;
model_3 = new DefaultTableModel();
table_1 = new JTable(model_3);
scrollPane_5.setViewportView(table_1);
Add row:
model_3.addRow(new Object[]{table.getValueAt(row,0) , table.getValueAt(row,1) ,table.getValueAt(row,2) , commentFood });
Remove Row:
model_3.removeRow(row); //row is an integer
Until here, it used to work properly. As you can see this table is defined as public because sometimes I need to fill it up from another JFrame in this way:
takeOrder to = new takeOrder();
//Get data from DB to resultSet
to.table_1.setModel(DbUtils.resultSetToTableModel(resultSet));
If I fill up the table in this way and try to add or remove my model_3, it will not work! Any suggestion that how I can add or remove to the table after using DbUtils.resultSetToTableModel(resultSet) will be appreciated.
As I couldn't find any information on the internet and I saw couple of people asked same question with no answer. I came up with this solution:
if (formOut) {
for (int i = 0; i < table_1.getRowCount(); i++) {
model_3.addRow(new Object[]{table_1.getValueAt(i,0),
table_1.getValueAt(i, 1), table_1.getValueAt(i, 2)});
}
}
formOut = false;
table_1.setModel(model_3);
fromOut is a boolean to check if I have used another model for my table. If so I add data from table to previous model, and then I reference that model to my table. Now I can add to that model as well.
I use a HashMap to fill a JTable, which is more or less continuously updated:
public Map< Long, MyObject > tableData = new HashMap< Long, MyObject >();
Every time a new element is added to the map the table model is notified:
tableData.put(id, anObject);
AbstractTableModel atm = (AbstractTableModel)model;
atm.fireTableDataChanged();
In Addition I have a TableRowSorter which sorts the rows according to a specific criteria:
TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
.
.
.
table.setRowSorter(sorter);
My goal is that the (vertical) scrollbar always jumps to the last added row, which can be somwhere in the mid
of the table because of the sorter probably using this:
table.scrollRectToVisible(table.getCellRect(row,0, true));
The problem is I do not know the index of the row :) Where can I hook in to get this index?
Scrolling to a newly inserted row in a potentially sorted table involves
listening to changes in the table model
converting the rowIndex of the event (it is in model coordiates) to view coordinates
scrolling to the view position
In code:
final JTable table = new JTable();
TableModelListener l = new TableModelListener() {
#Override
public void tableChanged(TableModelEvent e) {
if (TableUtilities.isInsert(e)) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
int viewRow = table.convertRowIndexToView(e.getFirstRow());
table.scrollRectToVisible(table.getCellRect(viewRow, 0, true));
}
});
}
}
};
table.getModel().addTableModelListener(l);
Two important aspects:
your model implemenation must fire the correct event, that is a insert, not a dataChanged
invoking both index conversion and scrolling guarantees that the table (which is listening to the model as well) has updated all internal state according to the model change.
How can i clear the content of the JTable using Java..
You must remove the data from the TableModel used for the table.
If using the DefaultTableModel, just set the row count to zero. This will delete the rows and fire the TableModelEvent to update the GUI.
JTable table;
…
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.setRowCount(0);
If you are using other TableModel, please check the documentation.
Basically, it depends on the TableModel that you are using for your JTable. If you are using the DefaultTableModel then you can do it in two ways:
DefaultTableModel dm = (DefaultTableModel)table.getModel();
dm.getDataVector().removeAllElements();
dm.fireTableDataChanged(); // notifies the JTable that the model has changed
or
DefaultTableModel dm = (DefaultTableModel)table.getModel();
while(dm.getRowCount() > 0)
{
dm.removeRow(0);
}
See the JavaDoc of DefaultTableModel for more details
I had to get clean table without columns. I have done folowing:
jMyTable.setModel(new DefaultTableModel());
This is the fastest and easiest way that I have found;
while (tableModel.getRowCount()>0)
{
tableModel.removeRow(0);
}
This clears the table lickety split and leaves it ready for new data.
I think you meant that you want to clear all the cells in the jTable and make it just like a new blank jTable.
For an example, if your table is myTable, you can do following.
DefaultTableModel model = new DefaultTableModel();
myTable.setModel(model);
If we use tMOdel.setRowCount(0); we can get Empty table.
DefaultTableModel tMOdel = (DefaultTableModel) jtableName.getModel();
tMOdel.setRowCount(0);
((DefaultTableModel)jTable3.getModel()).setNumRows(0); // delet all table row
Try This: