• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Tim Cooke
  • paul wheaton
Sheriffs:
  • Paul Clapham
  • Liutauras Vilda
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Piet Souris
  • Himai Minh
Bartenders:

JTable and Custom Columns

 
Ranch Hand
Posts: 479
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.








 
Rancher
Posts: 3291
30
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 479
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Rancher
Posts: 3291
30
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 479
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Rancher
Posts: 3291
30
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 479
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Rancher
Posts: 3291
30
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.
 
Liar, liar, pants on fire! refreshing plug:
The Low Tech Laboratory Movie Kickstarter is LIVE NOW!
https://www.kickstarter.com/projects/paulwheaton/low-tech
reply
    Bookmark Topic Watch Topic
  • New Topic