I'm using a JTable, and I need to allow moving of its columns. But there comes the problem. Once they have rearranged, it's like just they have changed there content and title only. But I also need their indexes to be changed as well.
To make this more clear, I'll give an example. Let's say my first column is called "names". When calling the 'setName()' method, a name must always go to that column, no matter where the column is. But not to the first column..Hope you got my point!
I've finished writing required methods. Hope there is a way to achieve this without touching the finished methods.
Any help is much appreciated!!!
To make this more clear, I'll give an example. Let's say my first column is called "names". When calling the 'setName()' method, a name must always go to that column, no matter where the column is. But not to the first column..Hope you got my point!
If you want to change the data, simply alter the underlying TableModel directly. The order of the columns never changes in the TableModel, it is only in the view (the JTable) that those columns are re-ordered.
If you do want to go through the table, you will have to convert from 'view-coordinates' to 'model-coordinates' by using the available JTable#convertColumnIndexToModel (view -> model) and the JTable#convertColumnIndexToView (model->view) methods as #MadProgrammer mentioned.
You should certainly not update the setValueAt method of the TableModel as you mentioned in one of your comments. As said before, the TableModel does not change the order of the columns, so the setValueAt should always be called with 'model coordinates', hence there is no need to transform those
Oh yeah, I love this, it always gets me ;)
Check out JTable.convertColumnIndexToModel(int viewColumnIndex) and JTable.convertColumnIndexToView(int modelColumnIndex)
Essentially, you need convert the column index to and from the view index.
You shouldn't need to worry about this with the TableModel as it's taken care for you my the JTable.
You'll have a similar issue with the RowSorter
Related
If I want to use a JTable in Java it seems to me for adding rows and doing alters from behind a button or so I always have to use a TableModel (this could be the default one or one created by your own) But my question is: Why do we have to use this. I can't find this in any of the posts I saw. Can someone explain how this works and why it is necessary? And why we can't just add rows to the JTable without a model.
It seems to me that if you want to just show a few records but at creation you don't know all the rows yet it would be easier to just do something like a table.add() to add the row.
You can create the table with data inside without a model attached to it. So why not add data?
Or am I just wrong and can you add also data without a model?
The TableModel interface defines the minimum methods needed by a JTable (view) to render its content (model). AbstractTableModel is an abstract implementation that provides the event plumbing and leaves just three methods that must be overridden. DefaultTableModel goes on to include an internal data model based on Vector and convenient methods to alter that internal model. See Creating a Table Model for a comparison and these contrasting examples.
So I am working on a GUI that involves working with tables that can be sorted. I am noticing that when I sort a table, and I select a row from the newly sorted table, the selected row index of that row points to the data row from before the sort. I understand that this is because the view has changed, but the model has not; thus, you have the need for convertRowIndexToModel. It is also to my understanding that one can automatically update the view based on changes to the model by firing TableModelEvent's.
So here is my question: is it possible to automatically update the TableModel, based on changes to the view, so that I would not have to worry about converting the view index to table index?
All the default table code does this automatically so you don't need to worry about this. That is if you reference the model by using the table.getValueAt(...) and table.setValueAt(...) methods then you won't have a problem.
Only code that you write that tries to access the TableModel directly will have a problem. In this case thats what the convertXXX(...) methods are for.
I would assume that I should use a jTable. I tried this, but I can't for the life of me figure out how to append, insert and delete rows without a ton of overrides and complicated code. I find it hard to believe that Oracle doesn't have an easier way to do it.
Here's the premise. I have a few arrayLists. Each contain n amount of items and I want to be able to add these items' properties in the form of strings to the jtable and once i surpass a certain number of rows, I want the jTable to scroll.
So that's the reason I need to be able to add and remove rows.
As discussed in How to Use Tables: Creating a Table Model, DefaultTableModel has convenient methods to add, insert and remove rows. Simply update your model using any of these methods and your view will be updated accordingly.
Addendum: There's an example here.
Take a look at GlazedLists. It makes working with dynamically changing data and sowing it in JTables/JLists/JTrees, etc, very simple.
In Netbeans, I created a JTable and bound it's values to a JPA result set. This works great. The query contains a parameter which I set in the pre-create box of the "query result" component. So just before Netbeans creates the query result I write this:
myQuery.setParameter("year", "1997");
This works fine. Now, I have an event handler which is supposed to change the parameter and display the new values in the table. So I do this:
myQuery.setParameter("year", "2005");
myResultList.clear();
myResultList.addAll(myQuery.getResultList());
jTable1.updateUI();
This works, but it feels wrong to me. Note: The result set is bound to the table. So I was hoping there was something like this:
myQuery.setParameter("year", "2005");
myResultList.refresh();
Is there something like this?
I finally figured it out...
The root of the problem lies in the JTableBinding class. Here's the important excerpt of the API doc:
If the List is an instance of ObservableList, then changes to the List contents (such as adding, removing or replacing an object) are also reflected in the JTable. Important: Changing the contents of a non-observable List while it is participating in a JTableBinding is unsupported, resulting in undefined behavior and possible exceptions.
And indeed, changing the list contents while it's not an observable list has weird behaviour in the resulting UI. If, for example, your initial query returns 1000 rows, and after the update the list only contains 100 rows, then the bound JTable still lets you try to scroll past the results. And the UI "hangs" for a short while.
In fact, when using JPA in Netbeans, and you use the appropriate components from the pallette, then you can easily fix this. The QueryResult "widget" has a checkbox labelles "observable". Check this one and you're done. Now all changes to the result will be reflected automatically in the JTable. So you can simply do:
myQuery.setParameter("year", "2005");
myResultList.clear();
myResultList.addAll(myQuery.getResultList());
without doing anything else.
Yes it is wrong, you should never use updateUI(). That method is used when you do a LAF change, which you haven't.
I don't know how Netbeans binding works, but yes if the model is update then it need to notify the table so the table can repaint itself.
If the binding recreates a new TableModel, then you should do
table.setModel( theNewModel );
If the model just updates itself, then it should invoke:
fireTableDataChanged(...);
I am doing project on java.
In one of the class, I am working on jtable.
Now what i am doing is,
In the table data will be loaded from the database.
Now i want to change some value at some exact row and column.
so for that i am using jtable's setValue function.
which is like this....
grayCardTbl.setValueAt(Float.valueOf(String.valueOf(pdiff)),1,4);
I have checked the "pdiff" variable, it is perfect.
i had total 5 columns and 10 rows. So now problem with rowindex and column index.
and after this i have also refresh the table. but still it is not reflecting on table.
The JTable.setValueAt(...) method calls TableModel.setValueAt(...).
My guess is that you've not implemented it in the model and the data doesn't get updated.
Edit: if your model calls JTable.setValueAt(...), it's going to loop into a stackoverflow. What you need to do is actually update the underlying data.
For instance if your model's getValueAt(...) does return data[row][column], then setValueAt(...) needs to do data[row][column] = value;