Java Tips Weblog

  • Blog Stats

    • 1,257,823 hits
  • Categories

  • Archives

Row Table Model

Posted by Rob Camick on November 21, 2008

The DefaultTableModel is a good general purpose model that allows great flexibility. It provides dynamic functionality when dealing with rows and columns. However, it has been my experience that most applications tend to deal with rows of data and dynamic rows more than column data and dynamic columns. So maybe if we remove the column functionality and improve the row functionality we can create a better general purpose table model.

The RowTableModel was designed to replace the AbstractTableModel as the base table model for tables that need to access data as rows of data. It will provide the storage for the data as well as the methods to access the data. It will also provide some convenience methods to make customizing the model easier.

The main functionality added is the ability to deal with rows of data easier. You don’t lose the cell related functionality, you just gain row level features. The row related methods are as follows:

  • addRow – convenience method that invokes insertRow to add a row Object to the end of the model
  • getRow – return the row Object at the specified row
  • getRowsAsArray – return the specified rows in an Array of the proper type
  • getRowsAsList – return the specified rows in a List of the proper type
  • insertRow – insert a row Object at the specified row in the model
  • insertRows – insert a List of row Objects at the specified row in the model
  • moveRow – move a range of row Objects to the specified location in the model
  • removeRowRange – remove a range of row Objects from the model
  • removeRows – remove 1 or more row Objects from the model
  • replaceRow – update the row with a new row Object

Now that we no longer need to worry about dynamic changes to the columns, we can add a few convenience methods to the model that will allow us to easily customize the behavour of the model.

  • setColumnClass – specify the class of individual columns
  • setModelEditable – specify editable property for the entire model.
  • setColumnEditable – specify editable property at a column level. This property will have preference over the model editable property.

The RowTableModel is an abstract class. It does not implement the getValueAt() or setValueAt() methods of the TableModel. This will allow you to extend the model to support row Objects of any type in the model. You will need to extend this class to implement these methods for your particular row Object type. For a simple example of how this might be done see the JButtonTableModel example code found below.

In my next couple of entries I will provide two concrete implementations. First, for rows of Lists, which can be used to replace the DefaultTableModel. The other will be a generic implementation for any bean Object.

Of course feel free to provide your own custom implementation for any of your classes. A custom implementation will always be more efficient than the generic implementations suggested above.

Get The Code

RowTableModel.java
JButtonTableModel.java

See Also

List Table Model
Bean Table Model

Related Reading

Creating a Table Model

11 Responses to “Row Table Model”

  1. rhuanca said

    Very good, this is very good.

  2. henrik said

    fantastic, thank you!!

  3. Jörg said

    Hello Rob,

    just a note of two typos:
    1. The last sentence of the description here: “A custom implementation will always be more efficient THAN …”

    2. The last sentence of the initial text in the source code: “methods either indirectly, … , or DIRECTLY.”

    Greetings

    Jörg

  4. dm1try said

    Thanks)
    you halp me…

  5. Thank you so much :).

  6. Sultan said

    Hello Rob, i have an ArrayList cointaining Orders, an order contains a String and a double value, how can i use your Row table model to make a table and display the objects in my ArrayList?

    • Rob Camick said

      You need to extend the RowTableModel and implement a couple of methods. Look at the JButtonTableModel.java example code that I provided for you to give you an idea how to do this.

  7. Sherebyah Tisbi said

    This is excellent piece of code Rob. I have class which doesn’t have get/set of properties but have a custom annotation Visible true/false and out of 7 properties 4 are visible true. I have my own TableModel extended from AbstractTableModel. I am preparing ArrayList of column names thru reflection and only creating columns which are visible true. But when I see the getColumnCount it returns 7 means all properties are taken up as columns. Dont understand how to fix this. Below is my SermonTableModel

    package com.tishbi.ui;

    import java.lang.reflect.Field;
    import java.util.ArrayList;

    import javax.swing.JCheckBox;
    import javax.swing.table.AbstractTableModel;
    import javax.swing.table.TableColumnModel;

    import com.tishbi.sitecontent.Sermon;
    import com.tishbi.sitecontent.TableMappings;
    import com.tishbi.sitecontent.AllEnums.DownloadStatus;
    import com.tishbi.util.Utilities;

    public class SermonTableModel extends AbstractTableModel
    {
    private static final long serialVersionUID = 1L;

    private ArrayList sermons;
    private ArrayList columns;
    Field[] properties = Sermon.class.getFields();

    public SermonTableModel(ArrayList _sermons, ArrayList _columns)
    {
    CollectColumns();
    this.sermons = _sermons;
    this.columns = _columns;
    }

    @Override
    public int getRowCount()
    {
    return sermons.size();
    }

    @Override
    public String getColumnName(int index)
    {
    String colname = null;
    if (index<columns.size())
    colname = columns.get(index);
    if (colname==null)
    colname = super.getColumnName(index);
    return colname;
    }

    @Override
    public Object getValueAt(int row, int col)
    {
    Sermon _sermon = sermons.get(row);
    switch(col)
    {
    case 0: return _sermon.Title;
    case 1: return _sermon.Length;
    case 2:
    {
    if (_sermon.Status==DownloadStatus.NOT_STARTED)
    return "0%";
    }
    case 3: return _sermon.isSermonSelected;
    default: return null;
    }
    }

    public Sermon getValueAt(int row)
    {
    return sermons.get(row);
    }

    public void setValueAt(Object obj, int row, int col)
    {
    if (col != 3) return;
    Sermon _sermon = sermons.get(row);
    _sermon.isSermonSelected = (boolean) obj;
    fireTableDataChanged();
    }

    public void setValueAt(Sermon sermon, int row)
    {
    sermons.remove(row);
    sermons.add(row, sermon);
    fireTableDataChanged();
    }

    @Override
    public Class getColumnClass(int index)
    {
    Class columnclass = null;
    if (index<columns.size())
    columnclass= getValueAt(0,index).getClass();

    if (columnclass == null)
    columnclass= super.getColumnClass(index);
    return columnclass;
    }

    @Override
    public boolean isCellEditable(int row, int col)
    {
    if (col ==3)
    return true;
    else
    return false;
    }

    public ArrayList getSermons()
    {
    return sermons;
    }

    @Override
    public int getColumnCount()
    {
    Field[] cols = Sermon.class.getFields();
    return cols.length;
    }

    public void addRow(Sermon _sermon)
    {
    sermons.add(_sermon);
    }

    private void CollectColumns()
    {
    columns = new ArrayList();
    for (Field f : properties)
    {
    TableMappings fieldAttributes = Utilities.MetaData(f);
    if (fieldAttributes.Visible())
    {
    columns.add(fieldAttributes.Header());
    }
    }
    fireTableStructureChanged();
    }
    }

    Will truly appreciate your help on this.

    • Rob Camick said

      This is a blog, not a forum. This question has nothing to do with the RowTableModel. I suggest you post your question in a proper forum for help. Also, I doubt people will be able to help you since you are using many custom classes. Question on a forum should include a SSCCE with the question so people can execute your code.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
Follow

Get every new post delivered to your Inbox.

Join 96 other followers

%d bloggers like this: