Win a copy of Murach's Python Programming this week in the Jython/Python forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Lost of row selection in JTable using fireTableDataChanged();  RSS feed

 
Greg Pata
Ranch Hand
Posts: 31
Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I am new to Java (4 days). Right now I am confronted to a problem I am not able to solve using Google and other sites. It would be very cool if you could give hints.
Everything is in the title. Specifically, in the following debug code, the popup menu item "Delete Row" has no effect due to the presence of the command "model.fireTableDataChanged();" which deselects the selected row... (fireTableDataChanged is here just for debug purpose)



To solve the problem I'd like to use removeTableModelListener(TableModelListener l) which "Removes a listener from the list that is notified each time a change to the data model occurs." However, I don't know how to do it... Is this the most effective way to solve it?

Cheers, Greg
 
Darryl Burke
Bartender
Posts: 5167
11
Java Netbeans IDE Opera
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Greg, and welcome to the Ranch!

Ids there a reason you don't query the table for its selectedRow before, instead of after, doing anything with the model?

Also note that if the table can be sorted, you will need to convert the rowIndex from view to model. JTable has a method for that.
 
Greg Pata
Ranch Hand
Posts: 31
Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you for your answer. In fact, the JTable I use in real life is updated several times per second and after each update fireTableDataChanged is applied.
That's why it appears in this debug program.
And thanks you for the last comment.
 
Rob Camick
Ranch Hand
Posts: 2754
12
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


You should never invoke that method. It is the job of the TableModel to invoke the appropriate method. In this case because a row is removed the TableModel will invoke fireTableRowsDeleted(...).
 
Greg Pata
Ranch Hand
Posts: 31
Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you Rob for your comment. Well, if I do not invoke this method in my initial code, the JTable is not updated. Consequently, I have to use this method.
The purpose of the debug code is just to show the lost row selection because of fireTableDataChanged. Indeed, in the debug code there is no use of it except that it highlights my problem.
 
Rob Camick
Ranch Hand
Posts: 2754
12
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No you do NOT need that statement.

In fact the code you posted will not work if you leave that line of code in there because you will no longer have a selected row to delete.

If you real code uses that statement it is wrong!!! Get rid of the statement it is not needed.

the JTable I use in real life is updated several times per second


Then this is the code we need to see. How do you update the data? Again it is the complete responsibility of the model to fire the appropriate event.

It sounds like you are updating the complete data of the TableModel? Why are you doing this. In this case of course the selection is removed because the table thinks you have completely new data so it does not make sense to keep the old selection.
 
Greg Pata
Ranch Hand
Posts: 31
Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you. I will try to use for instance fireTableCellUpdated instead. But it is not straightforward. I will let you know.
 
Rob Camick
Ranch Hand
Posts: 2754
12
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
> I will try to use for instance fireTableCellUpdated instead.

No. You use the setValueAt(...) method of the TableModel. And the TableModel invokes the fireTableCellUpdated() method.

Your application should never invoke a fireXXX() method directly. The functionality needs to be built into the TableModel.
 
Greg Pata
Ranch Hand
Posts: 31
Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Camick wrote:
Then this is the code we need to see.

Here is a new debug code which gives a better idea of the JTable model used in The code. The Feeder class is just here to see the lost of row selection. I do not know yet how to improve the model...
 
Paul Clapham
Sheriff
Posts: 22185
38
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And does this code still have the error you were describing? I don't see any code which replaces the whole model any more.
 
Greg Pata
Ranch Hand
Posts: 31
Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes. Due to line 147 the row selection is lost. The table is updated thanks to a feeder (lines 82/83).
 
Paul Clapham
Sheriff
Posts: 22185
38
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hmm... line 147 of what you posted looks like this:



But you meant line 147 from what you have in your text editor, right? Could you translate that into a line number from your post for us?
 
Paul Clapham
Sheriff
Posts: 22185
38
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm also confused by your TableActionListener class. I don't see why you need one of those for each row which is added to the model; and if you need one for every row I don't see why you don't remove a listener when you remove a row from the model. I also don't see that a TableActionListener actually does anything at all, unless the getSize() method of MyRow has a side effect. (That would be quite un-intuitive.) You also use == to compare two Strings in that listener, which is likely not to work the way you expect. You should usually use the equals() method to compare the contents of two objects, which I assume is your goal there.
 
Rob Camick
Ranch Hand
Posts: 2754
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Once again, only the TableModel is responsible for notifying the table that the data has changed. If the TableModel knows what data has changed then it can explicitly tell the table what has changed so you only paint data that has changed, not the whole table.

If you are externally updating your MyRow class then you need to tell the TableModel the MyRow data has changed and the TableModel will notify the Table.


I made the following change to your MyModel class:



Then I changed your MyRow class:



This is not the best solution because the MyModel class should not know anything about the TableModel. It should just be an object that happens to be stored in a TableModel.

It is probably better to use the Observable interface and register your MyRow object with your MyModel class when you add a row to the model, but I have never implemented this interface and don't have an example to give you.

 
Greg Pata
Ranch Hand
Posts: 31
Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Lol Paul. I really appreciate the joke. You posted the right question. I should have written an 8 )ine code.
 
Greg Pata
Ranch Hand
Posts: 31
Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you Paul for your last remark. Yes, all you wrote is right. I learnt something about equals.

Thank you Rob for your help. Amazing. I will work on my code which is as rigorous as the line counting of the Coderanch code editor.

Guys, you are brilliant. Cheers!

 
Rob Camick
Ranch Hand
Posts: 2754
12
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Just played with Observer/Observable and the code is straight forward.

The MyRow class just needs to extend Observer and invoke two methods when the data is changed. Also removed the dependencies on knowing about the TableModel class.

The MyModel class just needs to implement Observable and implement the update(...) method. Then the addRow(..) method needs to register the TableModel as an Observer.

 
Greg Pata
Ranch Hand
Posts: 31
Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Camick wrote:Just played with Observer/Observable and the code is straight forward.

Well, thank you Rob. This is great! What a solution!
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!