java JTable how to track rows - java

I have a JTable which is connected to sqlite. The db table looks like this:
resource_id #primary_key, file, type
I have already implemented adding the rows from db, but the problem is i need to know the resource id when some row in jTable is selected (not the index). Is there a way to add rows with unique ids and not based on indexes (or something similar)?
The current solution adds the resource id as a table column, but that doesnt solve the problem completely.

Create a class say TableData that contains the data from the table. Use a custom TableModel and place the data for the JTable in Vector<TableData>.
You may find it useful to create a method such as addRow(TableData data) in your TableModel that process the data from the table and adds data to the Vector.
In the overridden method public removeRow(int row) you will need to remove the vector data where row can serve as the index.
The overridden method public Object getValueAt(int row, int col) which is used to display the data in the JTable will then just need to retrieve the data from the Vector<TableData>. You can also place the logic for other columns which not part of the TableData in this method.
Dont forget to call fireTableRowsUpdated(row,col) and fireTableCellUpdated(row,col) where ever applicable.
For further reference and how to handling the selections in JTable you can refer this tutorial

Related

How to get data on JTable when using RowSorter?

I am having problem in getting the data when selecting a row from a JTable. This happens whenever I enable setAutoCreateRowSorter(true) of the table. So far this is what I did:
private void displayBooks(){
bookTable.setAutoCreateRowSorter(true);
bookTable.getTableHeader().setFont(new java.awt.Font("Century Gothic", 1, 14));
dtm = (DefaultTableModel) bookTable.getModel();
clearTable(dtm);
for(Book book: books){
dtm.addRow(new Object[]{book.getId(), ...//rest of the code
}
}
On the bookTableMouseClicked method this is what I did:
...
if(bookTable.getSelectedRow() >= 0){
Book book = books.get(bookTable.getSelectedRow());
setBook(book);
}...
I am now having ambiguous data when I clicked the header table to sort the data.
The selected row number on a JTable instance is always the selected row number on the view side.
If you activate row sorters this no longer matches the row number on the model side.
To transform between these two row numbers the JTable offers methods for converting from "view row index" to "model row index" and vice versa. These methods are named convertRowIndexToModel and convertRowIndexToView.
In your mouseClicked handler you need to call the function convertRowIndexToModel as follows:
if (bookTable.getSelectedRow() >= 0){
Book book = books.get(bookTable.convertRowIndexToModel(bookTable.getSelectedRow()));
setBook(book);
}
The problem is that you are storing data in two places:
in the TableModel
in an ArrayList
The data should only be stored in the TableModel. This way you don't need to worry about syncing the data since it is only in one place.
You could simply create a Book object from the selected row by using getValueAt(..) method of the JTable. You would need to invoke that method for each column in the table.
Or the other approach is to create a custom TableModel that holds Book objects, then you could just get the Book object directly from the table. This is a little more work, but it is the better approach.
Check out Row Table Model for a step-by-step approach on how to create a custom TableModel for a custom object.

How to add checkboxes to a JTable which uses a model with values from a database?

I have a model(AbstracTableModel) which I use to build a JTable.
The thing is that the table cell values seen in the GUI are displayed from a database.
How can I add a new column with checboxes for each row of the table?
Is there a concrete answer to this?
The thing is that the table cell values seen in the GUI are displayed from a database.
Use a DefaultTableModel to store the data from the database.
See the TableFromDatabaseExample.java code found in Table From Database for simple code to load the DefaultTableModel.
How can I add a new column with checboxes for each row of the table?
You can modify the above code to add an extra column to the "columnNames" Vector. Then in the looping code you add a Boolean.FALSE object to the "row" Vector.
Or, after creating the DefaultTableModel with the data from the database you can use the addColumn(...) method of the DefualtTableModel to create your column of check boxes.

JTable values not refreshed after tables is sorted

I have JTable object, filled with data provided from my implementation of AbstractTableModel. I have mouse event listener and when I click on some cell I get its row and column position. With this values I call getValueAt(int row, int column) method from TableModel and I get my data. The problem is the data in the table can be sorted when I click on column name. When again I try to call getValueAt() I get the old value
Example:
col1|col2
val11|val21
val12|val22
When I click on col1
values are:
col1|col2
val12|val22
val11|val21
The I call getValueAt(0,0) and still get val11, and I should get val12. How can I fix this ? Thanks!
The row index in the view (that you probably get from your mouse listener - if you posted the code as requested, we would know instead of having to guess) is not the same as the row index in the model, once the table is sorted. To convert from the view index to the model index, use convertRowIndexToModel().
Note that the same care must be taken for columns, as the user can reorder them by drag and dropping them.
I've manage to do it. table.getValueAt() should be called direct to the table object. My previous attempt was table.getModel().getValueAt().

How to insert a column at a specific position in JTable

I have a JTable with a predefined model
how to ask the model to insert a specific column in a specific position ?
so i want something like : DefaultTableModel.insertRow(int,Object[]) for columns
There is no insertColumn method like DefaultTableModel.insertRow() for inserting rows. In order to insert a column at a particular position, you must append the column using DefaultTable.addColumn() and then move the new column into the desired position.
JTable table = new JTable(rows, cols);
table.setAutoCreateColumnsFromModel(false);
DefaultTableModel model = (DefaultTableModel)table.getModel();
TableColumn col = new TableColumn(model.getColumnCount());
col.setHeaderValue(headerLabel);
table.addColumn(col);
model.addColumn(headerLabel.toString(), values);
table.moveColumn(table.getColumnCount()-1, vColIndex);
Is it really necessary to add the column in your TableModel at a specific index ? You can more easily adjust the column order in the view (the JTable) as documented in the class javadoc of JTable
By default, columns may be rearranged in the JTable so that the view's columns appear in a different order to the columns in the model. This does not affect the implementation of the model at all: when the columns are reordered, the JTable maintains the new order of the columns internally and converts its column indices before querying the model.
This is achieved by using the JTable#moveColumn method.
Adding a column to your DefaultTableModel is done calling the DefaultTableModel#addColumn method
With DefaultTableModel:
At the end one has to call fireDataChanged. There is only an addColumn with several overloads. This is no hindrance as the order of display is independent. One may move a column to another position, and has to take care of view index != column index. To get the correct view index immediately after adding the column, one has to access the JTable and call moveColumn.
I found it at times easier to create a new TableModel and assign that. Or not use the DefaultTableModel.
this link may help
http://www.roseindia.net/java/example/java/swing/InsertColumn.shtml
public void positionColumn(JTable table,int col_Index) {
table.moveColumn(table.getColumnCount()-1, col_Index);
}

getting selected row through AbstractTableModel

Is it possible to get the selected row index from my table model?
My object already knows about the table model. Instead of passing a reference to the table it self can i get the selected index using the model?
Like MrWiggles said you can get it from the ListSelectionModel which you is accessible from the table itself. However there are convenience methods in JTable to get the selected rows as well. If your table is sortable etc you will also need to go through the convertRowIndexToModel method :)
From the JTable JavaDoc:
int[] selection = table.getSelectedRows();
for (int i = 0; i < selection.length; i++) {
selection[i] = table.convertRowIndexToModel(selection[i]);
}
// selection is now in terms of the underlying TableModel
The TableModel only concerns itself with the data, the ListSelectionModel concerns itself with what is currently selected, so, no you can't get the selected row from the TableModel.
If you let your model class implement ListSelectionModel as well as TableModel, you will be able to get selection from one model... but you cannot extend two abstract model classes :-( (It also isn't very good idea anyway as your class will have too many responsibilities).
You can get the index from the bound Table and then you can use it to manipulate the table model. For example, if I want to delete a Row in my table model:
myTableModel.removeValueAt(myTable.getSelectedRow());

Categories