Last week, we had the author of TDD for a Shopping Website LiveProject. Friday at 11am Ranch time, Steven Solomon will be hosting a live TDD session just for us. See for the agenda and registration link
Hi. I am trying to figure out how to remove a row from a table. I created a table by passing it a model I created that extends DefaultTableModel. I also have a button in this app so whenever the button is pushed, it should run the method removeRow(int arg) from the model class I created. However, when I do this, I keep getting an ArrayIndexOutOfBounds error indicating that whatever row number I told it to remove is >= 0. Not sure what this means? Listed below is my class extending DefaultTableModel if that helps any. I have no idea what I'm doing wrong? Could someone clue me in? Thanks in advance!
I think the problem is that the default constructor for your class calls parent DefaultTableModel() constructor. According to the API this one creates a table with zero rows and zero columns. You can use one of the overloaded DefaultTableModel.setDataVector(...) method at the end of setData; which by the way, it seems to be performing the funtion of a constructor. Alternatively use a constructor in your class that calls super(dataRows, vectorOfColumns)
Jennifer, Check the documentation for the DefaultTableModel, and you'll find it stores data in a vector called dataVector, similar to your dataRows. Your code would work a lot better if you changed all references to dataRows to dataVector which you inherit from DefaultTableModel. You could delete dataRows from your own class. Hope that makes sense.
The nice thing about Standards is that there are so many to choose from!
Thanks for the help guys. However, in the meantime, I did a little more research and found it is best not to extend DefaultTableModel, but AbstractTableModel. So I found a class someone created on the web that is a JTable which contains the code in it to add and remove rows/columns using AbstractTableModel. So far it works great. In this class, there is some code for adding a TableSorter. I can get it to run, but I can't seem to get it to do anything. Whenever I click on the table headers, nothing happens. Could someone maybe look at this and tell me why?? I just don't get it. Thanks in advance.! Here's the class I found on the web:
What dou you expected to happen when clicking the table header? Notice that in the example it is not necessary to call this.setModel(tm); because tm still continues being the model for the table. By the way, have you taken a look at How to use Tables in the Java Tutorial? [ February 20, 2004: Message edited by: Jose Botella ]
When I click on the table header, I expect the data in the table to sort depending on which column header I press. This should happen since I have added a mouse listener to the table header. Since you brought it up, I see your point where tm continues being the table model, I overlooked that. I will remove it. (Keep in mind, I found this code on the internet ) In regards to your question, have I looked at How to Use Tables, yes I have. And I thought I understood them, more or less, however I keep running into little problems like the one above, as well as other little nagging questions I have about them. By the way, can you tell me, or send me somewhere that will tell me WHY AbstractTableModel is better to extend than DefaultTableModel? Thanks again for all of your help. I really appreciate it.
Hi Jennifer, DefaultTableModel extends AbstractTableModel so either way AbstractTableModel is in your inheritance chain. AbstractTableModel does not store any data. This is good for you because you're storing the data in your own class. DefaultTableModel has internal data storage implemented similarly to your way of using vectors, so there was a general conflict, in particular because you used a different name for your vector to DefaultTableModel's vector, so it was not overriding it. I can't find any reference anywhere to the SortedTable reference so I can't really help you with that. Can anyone help me with copying code from these pages? When I copy and paste into Textpad I find it all in one line and I have to manually put in all the line feeds. I must be doing it wrong - maybe ask this in the beginner's thread.
The nice thing about Standards is that there are so many to choose from!
The problem with DefaultTableModel is that it uses a Vector to store the data which is not considered to be very efficient. But in the case you do not have a lot of data it is easier to use instead of extending AbstractTableModel. Because you did not post the code for TableSorter I cannot tell what it is wrong wit it. Assuming such class changes the model of the table a TableModelEvent should be fired (i.e. AbstractTable.fireTableChanged(TableModelEvent e) ) for the table to show the changes. You can take a look at the example Sorting Columns in the magnificient book Swing 2nd ed. by Pavel and Robinson. ----------------------------------------------------------------------- Eddie I haven't used Textpad (JEdit is my favourite for quick examples) Have you configure it to java source code? [ February 22, 2004: Message edited by: Jose Botella ]
Thanks for the clarification on Abstract and Default table models! However, I still have the issue with the table sorting... Sorry I didn't post the code earlier. Here it is. Let me know if you need anything else! Thanks again for helping!
Okay. I've looked at the tutorial, and the 3 lines of code that it says is required to implement TableSorter. I have successfully done this before in a different application. The only difference with this one, is I am not passing the table constructor the sorter as the model. Instead, the model is being set in the SKTable constructor rather than passed. So everytime I try to click on the header, I am finding the output to the console is "Sorter not informed of change in model", And I don't know why! If I've set the table model to use the sorter, shouldn't it work? I just don't understand what I'm doing wrong. Thanks again for the help
The idea is that TableSorter should be the model for the table. And the original table's model should be the TableSorter's model. If you are calling addSorter method, the last sentence: this.setModel(sorter.getModel()); should be left out because it resets the previous model for the table that was correctly set with: this.setModel(sorter);
I tried removing this.setModel(sorter.getModel), and I'm still getting the same results: "Sorter not informed of change in Model". Right now what I have is in the constructor of SKTable I am calling the following method:
It seems to me it should be setting the model correctly?? So, any ideas why the sorter is still not getting informed of the changes in the model? Thanks again for all of your help.
Another point is: the original table's model should notify sorter of changes in the model, and sorter should notify the table. Extending from DefaultTableModel gives you these notifications for free. Extending from AbstractTableModel don't. But it is easy to write them:
Similarly with each of the methods that modify the content of the model. Consult the API for AbstractTableModel.fireXXX methods. Now, fireXXX methods will notify those listeners registered with AbstractTableModel.addTableModelListener . Notice the registration is done when you call sorter = new TableSorter(new SKTableModel()); by this code in TableMap class:
In TableMap there is also this piece of code:
That is, our TableSorter listens for changes in SKTableModel,and then passes these events to the TableModelListeners registered with it. The registration of SkTable with TableSorter takes place (according to API for JTable.setModel) when calling this.setModel(sorter); in SKTable.setModel Hope now it works.
SCJP2. Please Indent your code using UBB Code
On my planet I'm considered quite beautiful. Thanks to the poetry in this tiny ad:
free, earth-friendly heat - a kickstarter for putting coin in your pocket while saving the earth