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

Extending AbstractTableModel and DefaultTableColumnModel  RSS feed

 
Ralph Cook
Ranch Hand
Posts: 479
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a JTable in which I display different kinds of data; I have some integers, some strings, and some stuff for which I've written renderers.

I want my user to be able to choose things off a menu to select which columns are displayed, so the code needs to be able to insert/remove rows, etc.

The TableModel interface defines getColumnClass(int); it " Returns the most specific superclass for all the cell values in the column." AbstractTableModel.getColumnClass(int) "Returns Object.class regardless of columnIndex." DefaultTableModel does not implement the method.

My first thought was that TableColumn would have somewhere to store this column class, but it does not. I could extend TableColumn so that it had a "most specific superclass" stored for it; however, DefaultTableColumnModel stores its list of columns as a Vector<TableColumn>, so I can't store subclasses of TableColumn there (if you aren't familiar with generics, take my word for it or look it up). So if I store the column's class in an extension of TableColumn, that keeps me from using DefaultTableColumnModel or a subclass of it, or at least from storing my subclass of TableColumn in it.

The only two solutions I've thought of so far are (1) store the classes in a list in my own TableModel, separate from the 'real' list of TableColumns; this seems like a kludge, but a lot less trouble than (2) implementing TableColumnModel from scratch, so that it has a pass-through method for getting the column classes from an extended TableColumn. I suppose to be complete, I should create an interface that my subclass of TableColumn can implement; I can store my list of columns as a list of those instead of a list of a class.

I suppose I could (3) extend DefaultTableColumnModel, and build a vector of classes parallel to the vector of TableColumns. That might be better than storing it in the TableModel anyway.

But I thought I would ask for other suggestions. Has anyone else here implemented getColumnClass()?

rc
 
Darryl Burke
Bartender
Posts: 5167
11
Java Netbeans IDE Opera
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ralph Cook wrote:I could extend TableColumn so that it had a "most specific superclass" stored for it; however, DefaultTableColumnModel stores its list of columns as a Vector<TableColumn>, so I can't store subclasses of TableColumn there (if you aren't familiar with generics, take my word for it or look it up).

Huh? Generics doesn't preclude adding a subclass of the Type. More specifically, run this code and see for yourself.
 
Rob Spoor
Sheriff
Posts: 20893
81
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think Ralph means that you cannot limit the contents of this list to instances of his sub class.

Ralph Cook wrote:My first thought was that TableColumn would have somewhere to store this column class, but it does not.

No, but it does have the getModelIndex() method that returns the column number of the matching TableModel. Through that you can get the column class, but I was surprised to see the column had no reference to the JTable, TableColumnModel or TableModel at all. That reference will have to go through your business logic.

You usually create a sub class of AbstractTableModel or DefaultTableModel to return something more specific than Object.class; I often use a switch statement.
 
Ralph Cook
Ranch Hand
Posts: 479
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Spoor wrote:You usually create a sub class of AbstractTableModel or DefaultTableModel to return something more specific than Object.class; I often use a switch statement.


Well, yes I can do that, but it seems like such a kludge.

I have trouble understanding the conceptual model around JTable, possibly because no one documents conceptual models any more. From the TableColumn javadoc, we have:

javadoc wrote:A TableColumn represents all the attributes of a column in a JTable, such as width, resizibility, minimum and maximum width. In addition, the TableColumn provides slots for a renderer and an editor that can be used to display and edit the values in this column.


Except, evidently, the class associated with this column is NOT stored here.

So over in TableColumnModel, we have:

javadoc wrote:Defines the requirements for a table column model object suitable for use with JTable.


which really isn't very helpful. We see from its methods that it keeps a list of columns and retrieves individual columns, handles listener and selection things, and stores margins. Looks to me like this is a set of things that have to do with the collection of columns as they are in the table. I wouldn't think of this as the place to store a class associated with each column, and still wonder where they meant for that to be stored.

Now. I thought the whole point of the <? extends X> syntax in generics was to specify a collection of classes that are OR EXTEND another class. I thought, absent declaring your collection with that, that the system (compiler?) did prevent assigning a subclass of the object type into the collection. But you are correct: I added an extension to DefaultTableColumnModel to your code and called a method in it that accessed an extension of TableColumn, and it works. I'll have to go back now and see if it works with array lists as well as vectors. Thanks for pointing that out and completely confusing me on generics, which I thought I had (finally) figured out. (There is precious little conceptual explanation over there, also).

So that's opened up an option -- store my extension of TableColumn in the DefaultTableColumnModel.

Thanks to you both. I'm still looking for other ideas...

rc

p.s. if someone is interested in the generics question, I added a bit of code to satisfy myself that I could use it the way I would need to in this case
 
Rob Spoor
Sheriff
Posts: 20893
81
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ralph Cook wrote:
Rob Spoor wrote:You usually create a sub class of AbstractTableModel or DefaultTableModel to return something more specific than Object.class; I often use a switch statement.


Well, yes I can do that, but it seems like such a kludge.

I have trouble understanding the conceptual model around JTable, possibly because no one documents conceptual models any more.

TableColumnModel only specifies which of the model's columns are displayed in the JTable. It uses TableColumn for that. You can set renderers / editors for TableColumn because those are not part of the model, only of the view (JTable). Anything related to the data, such as the column class, goes in the TableModel. The JTable and cohorts use that information for displaying the data.
 
Ralph Cook
Ranch Hand
Posts: 479
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'd like to check out one more set of things I think I've figured out about JTables and columns.

TableColumnModel and DefaultTableColumnModel store information about visible columns. JTable.removeColumn(), for instance, removes the column reference from the protected Vector tableColumns, declared in DefaultTableColumnModel.

I have a class that defines a column that might be displayed -- it has default width, header, renderer, etc., i.e., things the program needs to know in order to add it to the view. I guess I'm supposed to put a collection of those into TableModel, since TableModel.getColumnCount() returns "the number of columns in the model".

It also says that JTable uses this count to determine how many columns to display by default. Can I override that default? If I have 10 columns and want to display 4 of them initially, how do I have the JTable do that instead of displaying 10? Surely they didn't construct this so that I have to have it display 10 and then remove 6.

rc
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!