Thursday, February 11, 2010

Bean reader JTable

I have already written about JTable on this blog, a lot can be written about it.
This time I will talk about a custom jtable I developed in order to have the simplest way to show READ ONLY data.

First how I was coding before:


class Person{
String firstName;
String lastName;
/*..*/
}

DefaultTableModel dtm= new DefaultTableModel();
for(Person p: getListPersons()){
Dtm.add(new Object[]{p.getFirstName(),p.getLastName()});
}

Dtm.addColumn(“firstName”);
Dtm.addColumn(“lastName”);

JTable table=new JTable();
table.setModel(dtm);


And to know which Object is currently selected:

Int index=table.getSelectedIndex();
Int modelIndex=table.convertRowIndexToModel(index);
Person selected=getListPersons.get(modelIndex);


After coding this way too many time I wondered:
As we only show only one kind of object in the table, wouldn’t it be easier:
to have a table of T
to be able to add/remove a T
to be able to get the selected T
All this without coding a custom JTable or/and TableModel each time


So the plan is to have an easy way to
-Define the class of objects to show using the JTable
-Define the columns
-Add/remove an object from the table
-Get the selected objects


So now let’s see the implementation I called BeanReaderJTable

First we need a generic parameter

public class BeanReaderJTable<T> extends JTable {/*…*/}


The contructor take the field names and the column names you want as header value.


public BeanReaderJTable(String[] fields, String[] title)


Adding/removing a row or getting the selected objects can’t be easier:

addRow(T)
addRow(T[])
addRow(Collection<T>)
removeRow(T)
getSelectedObject():T
getSelectedObjects():T[]



What is doing the actual job is the GenericTableModel.
The important job is done in getValueAt(int,int). The reflexion API is used to retrieve the value of a given pair field+row


Now let’s see a sample:


// declare the type + fields+column title
String[] fields = new String[] { "size", "size.width", "size.height", "class", "visible", null };
String[] titles = new String[] { "size", "width", "height", "class", "is visible", null };
BeanReaderJTable<Component> table = new BeanReaderJTable<Component>(fields, titles);
//populate the table
table.addRow(getAllComponents(frame));


You may have noticed, I left the last field empty, doing so, an empty column is created that can be used to set for example a button cell editor

And also what you can see, is that you can access nested field like size.width

This time you should actually be able to access the code source repository, my java.net project has been approved:
BeanReaderJTable





6 comments:

  1. That's great!

    But, the launch button links to PNG image..

    ReplyDelete
  2. hmm indeed , was pretty sure i added the link and tested in in the preview post, well anyway, it's fixed, thanks for the report

    ReplyDelete
  3. I've done something similar; I've created an extended JTableModel called JTableModelForEdit which adds add & remove methods and per-cell error messages and an associated JTableForEdit which renders this and adds easy navigation using the keypad (e.g. enter key to go to the next cell).

    Next I created a BeanTableModelForEdit which can be used like this:

    BeanTableModelForEdit lTableModel = new BeanTableModelForEdit(lData, new Column[]{ new Column("Col1" , "s1", true)
    , new Column("Col2" , "s2", true)
    , new Column("Col3" , "c1", true)
    , new Column("Col4" , "l1", true)
    , new Column("Col5" , "s3", true)
    });

    lData is a list of beans, each column has a title, a property name (in the testcode l1 is long1, s3 is string3) and an editable boolean.

    This is really useful when working with entities, e.g. when using Eclipselink or Hibernate.

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete
  5. Hello, my project try to make the same purpose but with annotation: http://beantablemodel.dev.java.net/

    Example of Read only POJO: https://beantablemodel.dev.java.net/source/browse/beantablemodel/tags/beantablemodel-1.0.2/demo/src/main/java/org/icroco/tablemodel/demo/BStockBasicRO.java?rev=215&view=markup

    ReplyDelete
  6. This comment has been removed by the author.

    ReplyDelete