tags:

views:

125

answers:

4

How can I associate my model class with entire row in JTable in order to get link to model class by row number?

A: 

You handle this by defining an implementation of TableModel. (http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/table/TableModel.html) Your TableModel class can store your data however you like. So, for example, you could have a list of objects where each element in the list represents an entire row.

David
OK, if so, how can I get row-model by row index? The only apropriate method I see - getValueAt() is used for rendering and column dependent.
kilonet
See my solution: The underlying data structure is a List whereby the list index is the model index and independent from the view changing (e.g. if the JTable is sorted).
Adamski
A: 
// Define underlying business object:
public class MyBusinessObject {
  private final int i;
  private final double d;
  private final String s;

  public MyBusinessObject(int i, double d, String s) {
    this.i = i;
    this.d = d;
    this.s = s;
  }

  public int getI() { return i; }
  public double getD() { return d; }
  public String getS() { return s; }
}

// Define TableModel implementation that "sits on" MyBusinessObject:
public class MyTableModel extends AbstractTableModel {
  private static final String[] COLUMN_NAMES = { "i", "d", "s" };
  private static final Class<?>[] COLUMN_CLASSES = { Integer.class, Double.class, String.class };

  static {
    assert COLUMN_NAMES.length == COLUMN_CLASSES.length;
  }

  // Collection of business objects.  Use ArrayList for efficient random access.
  private final List<MyBusinessObject> bizObj = new ArrayList<MyBusinessObject>();

  // TableModel methods delegate through to collection of MyBusinessObject.
  public int getColumnCount() { return COLUMN_NAMES.length; }
  public String[] getColumnNames() { return COLUMN_NAMES; }
  public Class<?>[] getColumnClasses() { return COLUMN_CLASSES; }
  public Object getValueAt(int row, int col) {
    Object ret;
    MyBusinessObject bo = bizObj.get(row);

    switch(col) {
      case 1:
        ret = bo.getI();
        break;
      case 2:
        ret = bo.getD();
        break;
      case 3:
        ret = bo.getS();
        break;
      default:
        throw new IllegalArgumentException("Invalid column index: " + col);
    }

    return ret;
  }

  // Additional methods for updating the collection.
  public void addBusinessObject(MyBusinessObject bo) {
    bizObj.add(bo);
    int i = bizObj.size() - 1;
    fireTableRowsInserted(i, i);
  }

  // ... etc.
}
Adamski
Sorry, but I can't see how can I get MyBusinessObject instance associated with specified row frow your example
kilonet
+1  A: 

Sorry, but I can't see how can I get MyBusinessObject instance associated with specified row

Well, you would need to add a getRow(...) method to return the appropriate business object.

I've written a generic RowTableModel that does this. It is an Abstract class however, you might be able to use the BeanTableModel which extends the RowTableModel. Or the example shows you how to easily extend RowTableModel by implementing a couple of methods.

Edit:

Add the following two lines to the end of the example:

frame.setVisible(true);
JButton first = model.getRow(0);
System.out.println(first);
camickr
it seems like a correct way. One little question about usage: ((RowTableModel<MyClass>)jtable.getModel()).getRow(row)?
kilonet
I don't see a question but I added a simple example above based on the JButtonTableModel example.
camickr
+1  A: 

I would suggest you take a look at GlazedLists which will work for any Domain Model object that follows Java Beans conventions (getter/setter).

Documentation is very good and there are good examples too.

GlazedLists also brings other interesting features (eg filtering), should you need them.

jfpoilpret