my dog learned polymorphism*
The moose likes Swing / AWT / SWT and the fly likes JTable and Custom Columns Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "JTable and Custom Columns" Watch "JTable and Custom Columns" New topic
Author

JTable and Custom Columns

Ralph Cook
Ranch Hand

Joined: May 29, 2005
Posts: 479
I apologize in advance for the length of this; I am hoping someone can point me in the right direction, and I include the code in case they want to look at that.

I am studying JTable and want to use a class to represent the columns that might be displayed on a given application. I have uses in mind for this that I will take up later; they do not appear here; the code is long enough as it is. As an example, I want to associate each possible column with a menu item the user can choose.

MyDisplayColumns extends Steven Kelvin's "ExtendedTableColumnModel", which has some code in it for holding references to columns that are not currently visible; I used Mr. Kelvin's code as a starting point.

When I run it now, I get a 5-column table, with left justified strings and right-justified numbers. If I click and drag the fourth column ("gradYr") to the left, it suddenly gets left-justified, and the column that moves to the right suddenly becomes right-justified. Yet, as near as I can tell, the getColumnClass method being called to get the class that determines the default rendering is returning the correct classes (Integer for the number, String for the string).

So if someone can explain to me where I should be looking to fix that, I'd appreciate it. What follows is a bunch of code; I don't know any way to cut it down if someone wants to run it.








Rob Camick
Ranch Hand

Joined: Jun 13, 2009
Posts: 2182
    
    7
Yes, the getColumnClass() method is use to determine the renderer/editor to be used for a given column.

You are overriding the getColumnClass() method of the TableModel. The order of the columns in the TableModel never changes. The TableModel is just used to store data and should not know anything about the TableColumnModel. Therefore you should not be referencing the custom TableColumnModel. Just return the proper Class based on the data in the TableModel. The fact that columns may be reordered is irrelevant to the TableModel.

For what its worth the Table Column Manager, allows you to hide/show columns and gives the users the ability to do this as well.
Ralph Cook
Ranch Hand

Joined: May 29, 2005
Posts: 479
In case someone wanted an answer closer to my question:

The class I started with, ExtendedTableColumnModel, extends TableColumnModel with the express purpose of storing non-visible columns and managing visibility based on method calls. Unfortunately, that class re-implemented moveColumn(int, int), which meant that moving a column in the view also changed its order in the list of all columns. As Rob pointed out, the order of the columns in "the model" is not supposed to change; I haven't figured out yet why the ETCM author did that. When I commented out the moveColumn (and removeColumn, for good measure) methods, it started working fine (i.e., the Integer and String data items were always justified correctly as I moved them around on the UI.

Thanks also for the pointer to another way to do this; I see it was posted *after* I was asking about this same subject some weeks ago. I didn't really like extending the TableColumnModel, but I'm still trying to get a conceptual understanding of column-handling in JTable, and that's turning out to be a lot more difficult than it should be...

rc
Rob Camick
Ranch Hand

Joined: Jun 13, 2009
Posts: 2182
    
    7
Unfortunately, that class re-implemented moveColumn(int, int), which meant that moving a column in the view also changed its order in the list of all columns.


That is correct, that is what should happen.

As Rob pointed out, the order of the columns in "the model" is not supposed to change;


That is not what I said. I said the order of the columns in the TABLE model is not supposed to change.

I suggested the problem was with you getColumnClass() method because it references your TableColumnModel. The TableModel should not access or care about the TableColumnModel.

but I'm still trying to get a conceptual understanding of column-handling in JTable, and that's turning out to be a lot more difficult than it should be...


The TableColumnModel is just a sequential List of how TableColumns are to be displayed for the table. When the TableColumnModel is created, the TableColumn's are displayed in the order in which the data in the TableModel is defined. Each TableColumn contains a column index back to the TableModel. So even if TableColum 5 is moved to the start of the TableColumnModel (and therefore the start of the table), the data for that coumn is still obtained by accessing the data from column 5 in the TableModel.

All table methods are relative to the table. Lets use the above example of column 5 being moved to the start of the table. If you invoke:

table.getValueAt(row, 0);

then the table must first convert the "0" to "5" so it can acess the data in column 5 of the TableModel. To do this is uses the

convertColumnIndexToModel(...) method.

The convertColumnIndexToModel() method uses the TableColumnModel (TCM) and TableColumn at position 0 of the TCM, to get the appropriate model index.

So any table method must first convert the "view" index to a "model" index.

The TableModel know nothing about the view so it always just uses the model index.
Ralph Cook
Ranch Hand

Joined: May 29, 2005
Posts: 479
Rob Camick wrote:
Unfortunately, that class re-implemented moveColumn(int, int), which meant that moving a column in the view also changed its order in the list of all columns.

That is correct, that is what should happen.

No, that was a bug. I said it was a bug; when I took that out, the program started working correctly. Evidently you are missing that the list that it was changing was the one you said should not change -- all the columns in the application, without regard to visibility. I can tell you think this list belongs in TableModel, but it isn't contained there in this example.
Rob Camick wrote:
As Rob pointed out, the order of the columns in "the model" is not supposed to change;

That is not what I said. I said the order of the columns in the TABLE model is not supposed to change.

Quite right, sorry.
Rob Camick wrote:
I suggested the problem was with you getColumnClass() method because it references your TableColumnModel. The TableModel should not access or care about the TableColumnModel.

But this TableColumnModel is extended by the class that handles all the columns. The TableModel cannot reference them separately. You wouldn't have needed to read the code to know this, I said it in the text.
Rob Camick
Ranch Hand

Joined: Jun 13, 2009
Posts: 2182
    
    7
MyDisplayColumns extends Steven Kelvin's "ExtendedTableColumnModel", which has some code in it for holding references to columns that are not currently visible; I used Mr. Kelvin's code as a starting point.


I have no idea what you started with and what you added. All I can tell you is that the final solution, although it may work, is WRONG from a design point of view.

You should NOT be creating a TableModel using a TableColumnModel. I don't know how to say this any differently: the TableModel should know nothing about the TableColumnModel. The whole point about MCV design is to separate the "model" from the "view".

No, that was a bug. I said it was a bug; when I took that out, the program started working correctly.


Maybe commenting out the moveColumn() method fixes your problem, but it doesn't fix your design. It is still wrong and I've explained why its wrong mulitple times.

Ralph Cook
Ranch Hand

Joined: May 29, 2005
Posts: 479
What you have said about the design is off-topic. I asked a question, and was able to figure out an answer for myself from something you said, for which I thank you (again).

It's normally called MVC, by the way. And I have no evidence that you know more about it than I do, no matter how many words you put in caps and boldface.

rc

Rob Camick
Ranch Hand

Joined: Jun 13, 2009
Posts: 2182
    
    7
It's normally called MVC,


That would be a typo on my par, but I'm impressed you do know how to spell it. Now all you have to do is learn what it means.

And I have no evidence that you know more about it than I do, no matter how many words you put in caps and boldface.


The evidence is in your code. You have absolutely no idea what you are doing. It does not follow MVC.

What you have said about the design is off-topic.


No it isn't because your stated goal is:

but I'm still trying to get a conceptual understanding of column-handling in JTable,

If you actually understood MVC then you would have a better chance at understanding why JTable works the way it does with the TCM and TC and TM.

A brute force solution is not a good solution. Even you have admitted you don't know why it works only that it does. If you look at my solution you will notice that I also have code related to moving columns. That is because this is the way the TCM was designed to be used.

I was asking about this same subject some weeks ago.


I saw that posting and did not offer my solution then because of your attitude towards Rob who was the only person who attempted to help you then. I see my original instinct was correct as you haven't learned anything.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: JTable and Custom Columns