3

I have different objects which is used to store the data from DB in an ArrayList<T>. I got to show records of each in a Table. I use an AbstractTableModel for first object am working on. The AbstractTableModel class has an ArrayList<Relation> and an String[] of headers.

My question is : How do I create the same AbstractTableModel that can be used for all objects. I mean if working with Relation, I can have ArrayList<Relation>, if with Product, can have ArrayList<Product> ..etc. Writing different AbstrastTableModel for each is not a good idea according to me. The main problem comes with setValueAt, getValue, addRow....

    @Override
public void setValueAt(Object value, int row, int col) {
    Relation r = data.get(row);     // ArrayList<Relation> data
    switch (col) {
        case 0:
            r.setId(value.toString());
            break;
        case 1: r.setName(value.toString());
            break;
        case 2: r.setStartBalance((Double)value);
            break;
        case 3: r.setCurrentBalance((Double)value);
            break;
    }
}

Any good idea to work on this as a single model that works for all. And can also fire events from here for the table.

I know it is a bit complicated. But the structure is vast and creating new class of AbstractTableModel and JTable for each object is also not a good idea.

What do you suggest ?

Kai
  • 38,985
  • 14
  • 88
  • 103
Tvd
  • 4,463
  • 18
  • 79
  • 125
  • just question, not clear for me, are you or aren't want to put diferrent Objects.Class to one Column or each Column has own Object.Class, both ways are pretty possible, – mKorbel Nov 25 '11 at 09:19
  • that looks [*] like an illegal implementatin of the model: it _must_ notify its listeners on change, that is fireXXUpdated. [*] "Looks", because it might be possible that the Relation is-a bean, that is fires on property changes, the model is listening to those changes and fires on receiving the change - which is the appropriate scenario anyway :-) – kleopatra Nov 25 '11 at 11:54
  • @kleopatra, that's how I do and it works great. Add/Reflect changes to model which in turn fires appropriately on receiving changes. – Tvd Nov 25 '11 at 14:19

2 Answers2

3

You can create an abstraction over your multiple data classes such that they expose methods like setValue(int columnNumber, Object Value) and similar getValue() method. Then you can write AbstractTableModel over this new abstraction. Afterwards creating required table model will just require changing the data class in constructor of your model.

For instance you can have an interface:

interface DBRow
{
    public void setValue(int columnNumber, Object value);
    public Object getValue(int columnNumber);
}

Both Product and Relation classes should implement this and then your model can work on DBRow interface.

You can also consider directly using resultset for populating tables: resultset-to-tablemodel

Ashwinee K Jha
  • 9,187
  • 2
  • 25
  • 19
  • Can you please elaborate your point. I am not clear 100%. Maybe just class defineations might get the idea better. – Tvd Nov 25 '11 at 09:41
  • Thanks AKJ, this helepd very well. Yet while adding & Editing I open a new window with text fields. For that I got to pass the object to correct Panel object. After adding/Editing from the Panel object, I again got to show this table.If that all worked well, then Best of all. – Tvd Nov 25 '11 at 11:37
0

In my opinion one AbstractTableModel should only be used for one object type. Maybe you should rethink your data model.

Anyway, the dirty way of solving this could be to use an ArrayList<Object> in your AbstractTableModel and check in your getValue()-method the type with instanceof. Then you can decide per object type which parameter you return of that particular object.

Example:

@Override
public void setValueAt(Object value, int row, int col) {
    Object r = data.get(row);     // ArrayList<Object> data
    switch (col) {
        case 0:
            if (r instanceof Relation) {
               ((Relation)r).setId(value.toString());
            } else {
               // do something with Product
            }
            break;
    }
}

Could that work for you?

Kai
  • 38,985
  • 14
  • 88
  • 103
  • I had this idea in mind already, but was thinking of a more better option to implement. – Tvd Nov 25 '11 at 09:43