Rephrasing of JTable question
Ok, I'm going to rephrase a question I put up pretty poorly about JTables. This is what how I see it. I wanted to create a JTable with a button as the last column, a delete button that will allow you to delete that row. Sounds simple enough - I figured out how to add that last column, and how to create my own TableCellRenderers such that it rendered the last column as a button representation.
Now my design question relates to the fact that the actual data, doesn't reside on the table...the actual data sits in another data object (a data array), and the table merely renders that information in a specific way. So when I hit the delete button, I really don't have a handle to the data, I need to somehow have an actionListener listening to that button which then sends a message to something else that is holding that data, and informs it to delete that item. The only way I see that is to pass a handle in the constructor of the TableCellRenderer of the actionListener which has a handle to the actual data. Is that how things are done? All this just so that an action performed on the Jtable looks like it's affecting the data itself?
Correct me if I'm wrong, but it seems like the implementation of this JTable has it such that even though when I addRows to the JTable I am passing an actual object to the JTable. The JTable will just convert the object into textual information, and the handle of that actual object will be lost. In some ways it seems like it would have been better if that JTable kept a handle to the object passed into it from addRow(), so that if I ever said delete this row, I don't have to jump through hoops to find which data object is represented by that particular row and then have something else delete. Instead it would say "Ok, delete this row, which is really this object." Or maybe there is a reason that isn't done.
Message was edited by:
deadseasquirrels
# 1
> Ok, I'm going to rephrase a question I put up pretty poorly about JTables.
And how are the people who read the other question first going to know that the old question is useless and a newer question exists?
Where in your other question do you redirect them to this posting?
> The JTable will just convert the object into textual information, and the handle of that actual object will be lost.
No the Object is stored in the TableModel. Unless you use a custom renderer the default renderer just uses the Object.toString() method to display the data in the cell.
> Now my design question relates to the fact that the actual data,
> doesn't reside on the table...the actual data sits in another data object (a data array),
Why would you store the data in two places? The whole point of using Models in Swing is to store data. If the DefaultTableModel doesn't store the data in a format that you like then you create a custom TableModel.
# 2
ok I see how the tableModel holds the actual data objects, and then a the defaultRender defines how that data is rendered, but is there way to add() an object[] into the tableModel, without displaying every element of the object[]? That is one of the reasons I have data in multiple places. My actual data objects have much more data in them that i use, but I do not necessarily want to display in the JTable.
# 3
Yes, you just add the data to the TableModel like any other data.
Then you tell the table which columns you don't what to be displayed, which means you remove TableColumns from the TableColumnModel. This posting has an example of this process:
http://forum.java.sun.com/thread.jspa?forumID=256&threadID=411506
# 4
hmm interesting, I'll give that a shot. So much of this implementation seems so convoluted and involved. It's like I'm trying to do one simple thing, and nothing is intuitive, and unless somebody explained it I don't think I would have ever figured it out.
# 5
also camickr you mention that there's no reason to create another data object[] to store the data that is in the TableModel, which I guess is true, since the TableModel stores objects, much like a Vector. But I guess I never saw swing components as data types. I mean it always seemed to me that Swing was the GUI layer and then there should a data layer. And in this way, although a JTable can in fact hold data (by means of the TableModel), I am not sure about it's efficiency or whether I should be mixing data layer and GUI layer.
Can somebody elaborate on whether this is alright, or if this is a bad design pattern? Or if JTables were made to hold actual data, and not just representations of data?
# 6
> Or if JTables were made to hold actual data,
JTable does not hold data, The TableModel holds the data
> and not just representations of data?
That is in fact what a JTable is. Its a "view" of the data.
This design is called Model-View-Controller (MVC) and all swing components follow this design. The data (Model) is separate from the view (component)
Maybe this article will help:
http://java.sun.com/products/jfc/tsc/articles/architecture/index.html
# 7
I read the post where you used the removeColumn method of the columnModel to remove the columns that you do not want to display. The way I understand it is that it is implementation of the MVC model, where the data is still there, but the Viewer aspect of the table just isn't displaying the data - and as you showed in your example, that gives more flexibility when you want to share a certain data table, but have it displayed differently.
But it seems to me that the lines of code:
columnModel1.removeColumn( columnModel1.getColumn( 4 ) );
should really be sitting in either the tableModel class, or the renderer class. At this point that line of code, which defines which columns table1 or table2 should display just sits in the main object class. It seems to me that to be more robust in your tableModel definition, somewhere it should say "any table that uses this table model will have columns x, y, z removed from the columnModel." Instead by having that line of code just sitting outside of either a renderer class or a tableModel class that line could be anywhere, and it doesn't seem too robust. I guess I'm mentioning it, because I would like to put it in either the renderer class or my tableModel class (shown below), but I don't see how I can do that. If I can't do that perhaps you can shed some light as to why my understanding is flawed, and why they designed it in such a way that you can't - right now it seems like the tableModel class would be a great place to put a line of code like that.
private DefaultTableModel filledTableModel = new DefaultTableModel(data, transactionCols){
// Only allow button column to be editable, if there is an actual
// button in that row
public boolean isCellEditable(int row, int col){
return (col == CANCEL_COL && getValueAt(row, col) != "") ? true : false;
}
// Overriden getColumnClass method that will return the object
// class type of the first instance of the data type otherwise
// returns the Object.class
public Class getColumnClass(int column){
for (int row = 0; row < getRowCount(); row++){
Object o = getValueAt(row, column);
if (o != null){ return o.getClass();
}
}
return Object.class;
}
};
# 8
> perhaps you can shed some light as to why my understanding is flawed,
I gave you a link on MVC. There are probably books written on MVC. I can't describe it in a few sentences.
A model has one function, to store data. It then notifies the view when the data changes so the view can repaint the data.
A view has one function to display data. The view can display the data however it wants.
> It seems to me that to be more robust in your tableModel definition,
> somewhere it should say "any table that uses this table model will
> have columns x, y, z removed from the columnModel
The TableModel knows absolutely nothing about the JTable or the fact that a table use a TableColumnModel to manage which columns are displayed in the view. That is the key to Model - View separation.
The TableModel doesn't know or doesn't care that you can rearrange the order of the columns. It doesn't know or care that you decied not to display all the columns of data.