DefaultTableModel or extend AbstractTableModel

I find the DefaultTableModel very easy to use with lots of functionality. As data is stored in a Vector of Vectors any data can be suppported. You don't have to worry about firing any events when cell data is changed, this is handled by the model. There is great support for dynamic tables through the addRow, addColumn methods. When processing needs to be done on a table as a result of a change in cell contents it is easy to use a TableModelListener.
In many question on this forum I find that people create there own table model by extending AbstractTableModel. Not only is this extra work, but you loose much of the functionality of the DefaultTableModel. One poster even said they believe that the DefaultTableModel should never be used in a production system suggesting that storing the data as a Vector of Vectors is inefficient and that too much casting is done when you need to do any processing.
Anyway, lets take a simple table with columns containing: quantity, price and cost. When the quantity or price is changed the cost should be calculated.
How would you implement this in production?
Is the DefaultTableModel sufficient for your needs or would you create your own TableModel.
Can you make a general statement about when you would use the DefaultTableModel vs. creating your own TableModel?
Following are two implementations of this table.
Any comments on either approach or suggestions on a third approach.
Using the DefaultTableModel:
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class TableProcessing extends JFrame implements TableModelListener
    JTable table;
    public TableProcessing()
        String[] columnNames = {"Item", "Quantity", "Price", "Cost"};
        Object[][] data =
            {"Bread", new Integer(1), new Double(1.11), new Double(1.11)},
            {"Milk", new Integer(1), new Double(2.22), new Double(2.22)},
            {"Tea", new Integer(1), new Double(3.33), new Double(3.33)},
            {"Cofee", new Integer(1), new Double(4.44), new Double(4.44)}
        DefaultTableModel model = new DefaultTableModel(data, columnNames);
        model.addTableModelListener( this );
        table = new JTable( model )
            //  Returning the Class of each column will allow different
            //  renderers to be used based on Class
            public Class getColumnClass(int column)
                return getValueAt(0, column).getClass();
            //  The Cost is not editable
            public boolean isCellEditable(int row, int column)
                if (column == 3)
                    return false;
                else
                    return true;
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        JScrollPane scrollPane = new JScrollPane( table );
        getContentPane().add( scrollPane );
     *  The cost is recalculated whenever the quantity or price is changed
    public void tableChanged(TableModelEvent e)
        if (e.getType() == TableModelEvent.UPDATE)
            int row = e.getFirstRow();
            int column = e.getColumn();
            if (column == 1 || column == 2)
                int    quantity = ((Integer)table.getValueAt(row, 1)).intValue();
                double price = ((Double)table.getValueAt(row, 2)).doubleValue();
                Double value = new Double(quantity * price);
                table.setValueAt(value, row, 3);
    public static void main(String[] args)
        TableProcessing frame = new TableProcessing();
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
}Extending AbstractTableModel:
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class TableProcessing2 extends JFrame
    JTable table;
    public TableProcessing2()
        ArrayList columnNames = new ArrayList(4);
        columnNames.add("Item");
        columnNames.add("Quantity");
        columnNames.add("Price");
        columnNames.add("Cost");
        ArrayList data = new ArrayList();
        data.add( new Item("Bread", 1, 1.11) );
        data.add( new Item("Milk", 1, 2.22) );
        data.add( new Item("Tea", 1, 3.33) );
        data.add( new Item("Cofee", 1, 4.44) );
        TableModel model = new ItemTableModel(data, columnNames);
        table = new JTable( model );
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        JScrollPane scrollPane = new JScrollPane( table );
        getContentPane().add( scrollPane );
    class Item
        String name;
        int quantity;
        double price;
        double cost;
        public Item(String name, int quantity, double price)
            this.name = name;
            this.quantity = quantity;
            this.price = price;
            cost = quantity * price;
    class ItemTableModel extends AbstractTableModel
        List data;
        List columnNames;
        public ItemTableModel(List data, List columnNames)
            this.data = data;
            this.columnNames = columnNames;
        public String getColumnName(int col) { return columnNames.get(col).toString(); }
        public int getRowCount() { return data.size(); }
        public int getColumnCount() { return columnNames.size(); }
        public Class getColumnClass(int column) { return getValueAt(0, column).getClass(); }
        public boolean isCellEditable(int row, int column)
            if (column == 3)
                return false;
            else
                return true;
        public Object getValueAt(int row, int column)
            Item item = (Item)data.get( row );
            switch ( column )
                case 0: return item.name;
                case 1: return new Integer(item.quantity);
                case 2: return new Double(item.price);
                case 3: return new Double(item.cost);
            return null;
        public void setValueAt(Object value, int row, int column)
            Item item = (Item)data.get( row );
            switch ( column )
                case 0:
                    item.name = (String)value;
                    break;
                case 1:
                    item.quantity = ((Integer)value).intValue();
                    break;
                case 2:
                    item.price = ((Double)value).doubleValue();
                    break;
                case 3:
                    item.cost = ((Double)value).doubleValue();
                    break;
            fireTableCellUpdated(row, column);
            //  Update dependent cells
            if (column == 1 || column == 2)
                Double cost = new Double(item.quantity * item.price);
                table.setValueAt(cost, row, 3);
    public static void main(String[] args)
        TableProcessing2 frame = new TableProcessing2();
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
}

mzarra, I think I have enough information to make an informed decision, thanks.
virivan,
I took a look at your link. Cool. It looks like you've played with tables more than me. Like mzarra said above, you are probably creating your TableModel in the event thread which doesn't give the GUI a chance to repaint itself. When the table was loading I clicked on a different window and when I clicked back on you application I got a 'black' rectangle on the screen.
Reply 3 of this thread shows a simple example of moving the logic from the event thread to a separate thread:
http://forum.java.sun.com/thread.jsp?forum=57&thread=435487
Also, for fun I created a simple TableModel to store sparse data. It loads instantly. Here's the code I used:
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
public class TableSparse extends JFrame
    private final static String[] LETTERS =
        "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
        "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"
    public TableSparse(int row, int column)
        TableModel model = new LargeTableModel(row, column);
        JTable table = new JTable(model);
        table.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );
        JScrollPane scrollPane = new JScrollPane( table );
        getContentPane().add( scrollPane );
//        JTable lineTable = new LineNumberTable( table );
//        scrollPane.setRowHeaderView( lineTable );
    class LargeTableModel extends AbstractTableModel
        HashMap data = new HashMap();
        int rows;
        int columns;
        public LargeTableModel(int rows, int columns)
            this.rows = rows;
            this.columns = columns;
        public String getColumnName(int column)
            if (column < 26)
                return LETTERS[column];
            int first = (column / 26) - 1;
            int second = (column % 26);
            return LETTERS[first] + LETTERS[second];
        public int getRowCount() { return rows; }
        public int getColumnCount() { return columns; }
        public boolean isCellEditable(int row, int column) { return true; }
        public Object getValueAt(int row, int column)
            //  Check for row
            Integer key = new Integer(row);
            Object o = data.get(key);
            if (o == null) return null;
            //  Now check for column
            HashMap rows = (HashMap)o;
            key = new Integer(column);
            return rows.get(key);
        public void setValueAt(Object value, int row, int column)
            //  Remove cell data
            if (value.toString().equals(""))
                removeCellData(row, column);
                return;
            //  Save cell data
            Integer key = new Integer(row);
            HashMap rows = (HashMap)data.get(key);
            if (rows == null)
                rows = new HashMap();
                data.put(key, rows);
            key = new Integer(column);
            rows.put(key, value);
        private void removeCellData(int row, int column)
            Integer rowKey = new Integer(row);
            HashMap rows = (HashMap)data.get(rowKey);
            Integer columnKey = new Integer(column);
            rows.remove(columnKey);
            if (rows.isEmpty())
                data.remove(rowKey);
    public static void main(String[] args)
        TableSparse frame = new TableSparse(64000, 256);
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
        frame.pack();
        frame.setVisible(true);
}

Similar Messages

  • Javadoc bug or missing an option for class extending AbstractTableModel

    Hi Everybody,
    I am reviewing my javadoc before submission of my SCJD assignment and I noticed
    for my JTable model class HotelRoomTableModel that extends AbstractTableModel
    for all the overwritten methods like getValueAt(), getColumnCount(), getRowCount()
    that implement the TableModel interface where I am using javadoc comments of the form:
    * {@inheritDoc}
    @Override the HTML generated javadoc I see in my browser doesn't show anything
    for these methods other than the name and the signature of the method.
    Is that normal? Or is it a bug? Or perhaps did I miss anything?
    I would hope that it would show something like:
    "Specified by: methodName in interface InterfaceName"
    or
    "Overrides: methodMame in class ClassName".
    My environment:
    [auyantepui]</home/morillo/src/java/scjd/submission>% java -version
    java version "1.6.0_18"
    Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
    Java HotSpot(TM) Server VM (build 16.0-b13, mixed mode)
    [auyantepui]</home/morillo/src/java/scjd/submission>% cat /etc/release
                           Solaris 10 5/09 s10s_u7wos_08 SPARC
               Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
                            Use is subject to license terms.
                                 Assembled 30 March 2009
    [auyantepui]</home/morillo/src/java/scjd/submission>% uname -a
    SunOS auyantepui 5.10 Generic_139555-08 sun4u sparc SUNW,Sun-Blade-1000
    [auyantepui]</home/morillo/src/java/scjd/submission>%Any ideas?
    Thanks,
    Carlos.

    He quoted the Javadoc which says you have to have the source code available for the Javadoc you are trying to inherit. All I am doing here is restating that, which really is pointless and valueless.It needs the source so that it can copy the documentation you want to copy, which I would have thought was obvious in the first place >
    ejp, there is no need to be such an arrogant jerk responding. It is not my fault if you are having a bad day.
    I wrote above:
    TableModel interface is in javax.swing.table. It is not part of my source code.I am only asking for help and I thought that was the purpose of this forum.
    I am not here to get a smart ass response with such an arrogance and attitude.

  • Pass a value to a class that extends AbstractTableModel

    Hi
    I have a problem with a table model that I cannot find a way of overcoming.
    I have created a class called MyTableModel that extends AbstractTableModel.
    MyTableModel creates and uses another class that I have defined in order to retrieve records from a database, MyTableModel fills the table with these records.
    However, I wish to alter my class in order to provide an int parameter that will act as a �where� value in the classes sql query.
    The problem is this, I cannot work out how to pass a value into MyTableModel. I have tried creating a simple constructor in order to pass the value but it doesn�t work.
    My code is shown below:
    import BusinessObjects.JobItemClass;
    import DBCommunication.*;
    import java.util.ArrayList;
    import javax.swing.table.AbstractTableModel;
    public class MyJobItemTableModel extends AbstractTableModel
      public MyJobItemTableModel(int j)
          jobNo = j;
      int jobNo;
      JobAllItems jobItems = new JobAllItems(jobNo);
      ArrayList items = jobItems.getItems();
      String columnName[] = { "Item Number", "Item Description", "Cost per item", "Quantity" };
      int c = items.size();
      Class columnType[] = { Integer.class, String.class, Double.class, Integer.class };
      Object table[][] =  new Object[c][4];
      public void fillTable()
          if(c > 0)
            for (int i = 0; i < c; i = i + 1)
              this.setValueAt(((JobItemClass) items.get(i)).getItemNumber(), i, 0);
              this.setValueAt(((JobItemClass) items.get(i)).getDescription(), i, 1);
              this.setValueAt(((JobItemClass) items.get(i)).getCostPerItem(), i, 2);
              this.setValueAt(((JobItemClass) items.get(i)).getQuantity(), i, 3);
      public void setJobNo(int s)
          jobNo = s;
      public int getColumnCount()
          if(c > 0)
            return table[0].length;
          else
              return 0;
      public int getRowCount()
        return table.length;
      public Object getValueAt(int r, int c)
        return table[r][c];
      public String getColumnName(int column)
        return columnName[column];
      public Class getColumnClass(int c)
        return columnType[c];
      public boolean isCellEditable(int r, int c)
        return false;
      public void setValueAt(Object aValue, int r, int c)
          table[r][c] = aValue;
    }Any advice will be appreciated.
    Many Thanks
    GB

    your JobAllItems is created before constructor code is run (since it is initialized in class member declaration)
    use something like
    public MyJobItemTableModel(int j)
          jobNo = j;
          items = (new JobAllItems(jobNo)).getItems();
          c = items.size();
          table =   new Object[c][4];
      int jobNo;
      ArrayList items;
      String columnName[] = { "Item Number", "Item Description", "Cost per item", "Quantity" };
      int c;
      Class columnType[] = { Integer.class, String.class, Double.class, Integer.class };
      Object table[][] ;instead of
    public MyJobItemTableModel(int j)
          jobNo = j;
      int jobNo;
      JobAllItems jobItems = new JobAllItems(jobNo);
      ArrayList items = jobItems.getItems();
      String columnName[] = { "Item Number", "Item Description", "Cost per item", "Quantity" };
      int c = items.size();
      Class columnType[] = { Integer.class, String.class, Double.class, Integer.class };
      Object table[][] =  new Object[c][4];

  • Is it better to use AbstractTableModel or DefaultTableModel...?

    Is it better to use AbstractTableModel or DefaultTableModel when subclassing your jtable model? I ask this because while the java tutorial seems to point to the former I've read some people to recommend using the defaulttablemodel. What is the general consensus? Do you have to implement all the methods you need in the defaulttablemodel also? Because right now I think that's the biggest drawback that abstracttablemodel has...

    I ask this because while the java tutorial seems to point to the former (AbstractTableModel)Because they are trying to show an example of how to implement a TableModel. This does not mean you need to create a custom TableModel every time you use a JTable
    I've read some people to recommend using the defaulttablemodel.Because it is fully functional. DefaultTableModel already extends AbstractTableModel to provide this functionality. If it has the functionality that you require then there is no need to create another custom TableModel
    Is it better to use AbstractTableModel or DefaultTableModel...?In general, if the DefaultTableModel does not meet your needs because of the format of your data then you would extend the AbstractTableModel. But if your needs are similiar to the functionality already provided by the DTM then it may be faster/easier to extend it.
    You can't use the AbstractTableModel as is and therefore always need to extend it to implement the functionality that you require. Extending the AbstractTableModel every time doesn't make any sense because you keep doing extra work. So if you do need to extend it you should extend it in a generic way that the classes are reusable.
    Which is why I created the [List Table Model|http://www.camick.com/java/blog.html?name=list-table-model] and [Bean Table Model|http://www.camick.com/java/blog.html?name=bean-table-model]. The idea is to minimize the coding effort involved. They allow you to work with Lists. They can be used as is, or with smaller customization than required if you use the ATM every time.
    Edited by: camickr on May 9, 2009 1:01 AM

  • How to delete a row from AbstractTableModel

    my table is using an object to populate the data.
    static Object[][] data = new Object[LineCount()][5];
    So when I delete a row, I should delete from the model or the object?
    Rgds

    When you populate your table with a two dimensional array, the table actually creates a DefaultTableModel (which extends AbstractTableModel). The DefaultTableModel has methods which allow you to add/remove row from the data model. Read the DefaultTableModel API for more information.

  • JTableModel

    I have a problem with my JTableModel. every time the first query returns no rows, the second query with some values is not able to create a new table model.
    If the preceding rows have values, i can run as many queries as possible.
    How do i sort this out?
    public void getTable(){
          //getting a select statement from a function that generates it from the GUI 
            String whereclause=getCriteria();
            try {
                model=new JTableModelClass(whereclause,columnNames);
                table.setModel(model);
                table.setPreferredScrollableViewportSize(new Dimension(500, 70));
                table.setFillsViewportHeight(true);
                table.setAutoCreateRowSorter(true);
                table.getTableHeader().setReorderingAllowed(true);
                if(scrollPane==null){
                    scrollPane = new JScrollPane();
                    scrollPane.setViewportView(table);
                } else{
                    scrollPane.setViewportView(table);
                scrollPane.setSize(900,400);
                scrollPane.setBounds(0,0,900,400);
                scrollPane.setWheelScrollingEnabled(true);
                scrollPane.createHorizontalScrollBar();
                this.jPanel3.add(scrollPane);
            catch(Exception eta){
                System.out.println("Error in setting a table model :  "+eta.getMessage());
    public class JTableModelClass extends AbstractTableModel {
        Object [][] data;
        JTable table;
        Vector vectordata,rowdata;
        String[] columnNames;
        JDataBase db=new JDataBase();
        /** Creates a new instance of JTableModelClass */
        public JTableModelClass(String query, Vector colnames) {
            columnNames=new String[colnames.size()];
            String myquery=query;
            String conn=db.connection.toString();
            vectordata=db.getData(query);
            for(int i=0;i<colnames.size();i++){
                columnNames=(String)colnames.elementAt(i);
    System.out.println("get no of rows");
    int rows=db.no_rows;
    Object row;
    data=new Object[rows][columnNames.length];
    if(rows==0){
    System.out.println("No Such Data Found");
    } else{
    System.out.println("Some Data Found");
    for(int i=0;i<rows;i++){
    rowdata=(Vector)vectordata.elementAt(i);
    for(int j=0;j<columnNames.length;j++){
    data[i][j]=rowdata.elementAt(j);
    System.out.println("making a table done");
    public int getColumnCount() {
    return columnNames.length;
    public int getRowCount() {
    return data.length;
    public String[] getTableHeader(){    
    return columnNames;
    public void addRow(Object[] row) {
    for (int i=0; i<columnNames.length; i++) {
    data[data.length+1][i] = row[i];
    fireTableRowsUpdated(data.length+1,data.length+1);
    public String getColumnName(int col) {
    return columnNames[col];
    public Object getValueAt(int row, int col) {
    return data[row][col];
    public Class getColumnClass(int c) {
    return getValueAt(0, c).getClass();
    public static void main(String[] args) {

    Don't multi-post.
    My response in your last posting said "In The Future".
    Anyway you where given an answer so there was no need to repost.
    The DefaultTableModel does extend AbstractTableModel. So you copy your ResultSet to the DefaultTableModel.
    Take time to understand the suggestion given to you before cluttering the forums with multiple postings.
    hope everyone knows that the Abstract table model needs a rowData [][], which is a 2D arrayNo it doesn't. An AbstractTableModel does not provide any storage of the data which is why you need to implement all the methods yourself.

  • Exception with DefaultTableModel

    Dear all,
    I want to instatiate this class and add to my JTable. However, I can't make an instance of this.
    If I extend AbstractTableModel my code is working fine but with DefaultTableModel I get the exception: "Exception caught in Scenegraph: null".
    Why do I get null exception in this code?
    !!!Please notice that the code is working fine with AbstractTableModel but not with DefaultTableModel!!!
    import javax.swing.JTable;
    import javax.swing.table.AbstractTableModel;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.JScrollPane;
    import javax.swing.JFrame;
    import javax.swing.SwingUtilities;
    import javax.swing.JOptionPane;
    import java.awt.*;
    import java.awt.event.*;
    import java.lang.*;
    import javax.swing.DefaultCellEditor;
    import java.util.Vector;
    //public class MyTableModel extends AbstractTableModel
    public class MyTableModel extends DefaultTableModel
    private boolean DEBUG = true;
    final String[] columnNames = {"IFCOBJECTS OR PROCESSES", "QUANTITY", "UNITS", "UNIT COST (?)", "TOTAL COST (?)"};
    static Object[][] data = new Object[IFC_Tree.totalVector.size()][5];
    static double totalCost = 0.0;
    public MyTableModel()
    for(int i=0; i < IFC_Tree.totalVector.size(); i++)
    Vector tmp = (Vector)(IFC_Tree.totalVector.elementAt(i));
    for(int j=0; j < tmp.size(); j++)
    Object value = tmp.get(j);
    data[i][j] = value;
    public int getColumnCount()
    return columnNames.length;
    public int getRowCount()
    return data.length;
    public String getColumnName(int col)
    return columnNames[col];
    public Object getValueAt(int row, int col)
    return data[row][col];
    public boolean isCellEditable(int row, int col)
    if (col < 3)
    return false;
    else if (col == 3)
    return true;
    else
    return false;
    public void setValueAt(Object value, int row, int col)
    data[row][col] = value;
    fireTableCellUpdated(row, col);
    if(col == 3)
    try
    String str = (String)data[row][col];
    data[row][col+1] = new Double( ((Float)data[row][col-2]).doubleValue() * Double.valueOf(str).doubleValue() );
    fireTableCellUpdated(row, col+1);
    totalCost = 0.0;
    for (int k=0; k<TableDemo.costTable.getRowCount(); k++)
    totalCost = totalCost + ((Double)data[k][4]).doubleValue();
    data[TableDemo.costTable.getRowCount() - 1][4] = new Double (totalCost);
    fireTableCellUpdated(TableDemo.costTable.getRowCount() - 1, 4);
    catch(Exception ex)
    System.out.println("Exception caught in MyTableModel class: INVALID INPUT " + ex.getMessage());
    System.out.println(":-(");
    private void printDebugData()
    int numRows = getRowCount();
    int numCols = getColumnCount();
    for (int i=0; i < numRows; i++)
    System.out.print("row " + i + ":");
    for (int j=0; j < numCols; j++)
    System.out.print(" " + data[i][j]);
    System.out.println();
    }

    Hi vreznik;
    Actually, my original code is just exactly the same you suggested.
    I get the exception with DefaultTableModel only.
    public MyTableModel()
    //System.out.println("TableModel_1");
    for(int h=0; h < IFC_Tree.totalVector.size(); h++)
    Vector tmp = (Vector)(IFC_Tree.totalVector.elementAt(i));
    for(int j=0; j < tmp.size(); j++)
    Object value = tmp.get(j);
    data[h][j] = value;
    }

  • AbstractTableModel-- Delete a row (pls help.....)

    Hi !
    I have a JTable of AbstractTableModel. now if i have to delete a row how can I ?
    pls post a sample code...
    FYI : This is my JTable
    class ViewTable extends AbstractTableModel{
        private String[] columnNames = {"COMP",
                                        "FILE NAME",
                                        "FILE LOCATION",
                                        "HOT #",
                                        "APPLIED ON",
                                        "DELETE"};
        private Object [][] data  = new Object [50][6];
        private Class types[]=new Class[]{ String.class,String.class,String.class,String.class,String.class,Boolean.class};
        public  void setValues()
             for(int i=0;i< data.length;i++)
                  data[0]=null;
              data[i][1]=null;
              data[i][2]=null;
              data[i][3]=null;
              data[i][4]=null;
              data[i][5]=new Boolean(false);
    public int getColumnCount() {
    return columnNames.length;
    public int getRowCount() {
    return data.length;
    public String getColumnName(int col) {
    return columnNames[col];
    public Object getValueAt(int row, int col) {
    return data[row][col];
    public Class getColumnClass(int c) {
    return types[c];
    public boolean isCellEditable(int row, int col) {
    //Note that the data/cell address is constant,
    //no matter where the cell appears onscreen.
    if (col < 2) {
    return false;
    } else {
    return true;
    * Don't need to implement this method unless your table's
    * data can change.
    public void setValueAt(Object value, int row, int col) {
    data[row][col] = value;
    fireTableCellUpdated(row, col);
    I create the Table like this...ViewTable VT= new ViewTable();
    view_table = new JTable(VT);

    dashok.83 wrote:
    yes.. How can I have the last column as checkBox....Make the last column boolean. You should extend the DefaultTableModel class and override the getColumnClass to return the appropriate class to get the appropriate behaviour (for instance I think that it's Boolean.class to get a check mark). Have you looked through the Sun tutorials on this? You should do this before asking the question here.

  • DefaultTableModel Problem

    Dear all,
    I am trying to build a JTable with the below class. If I extend AbstractTableModel my code is working fine but with DefaultTableModel I get the exception: "Exception caught in ...: null".
    Why do I get null exception in this code? I can't create an instance of the below class with DefaultTableModel.
    !!!Please notice that the code is working fine with AbstractTableModel but not with DefaultTableModel!!!
    //CLASS_1
    MyTableModel myModel = new MyTableModel();
    JTable costTable = new JTable(myModel);
    //CLASS_2
    import javax.swing.JTable;
    import javax.swing.table.AbstractTableModel;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.JScrollPane;
    import javax.swing.JFrame;
    import javax.swing.SwingUtilities;
    import javax.swing.JOptionPane;
    import java.awt.*;
    import java.awt.event.*;
    import java.lang.*;
    import javax.swing.DefaultCellEditor;
    import java.util.Vector;
    //public class MyTableModel extends AbstractTableModel
    public class MyTableModel extends DefaultTableModel
    private boolean DEBUG = true;
    final String[] columnNames = {"IFCOBJECTS OR PROCESSES", "QUANTITY", "UNITS", "UNIT COST (?)", "TOTAL COST (?)"};
    static Object[][] data = new Object[IFC_Tree.totalVector.size()][5];
    static double totalCost = 0.0;
    public MyTableModel()
    for(int m=0; m < IFC_Tree.totalVector.size(); m++)
    Vector tmp = (Vector)(IFC_Tree.totalVector.elementAt(m));
    for(int n=0; n < tmp.size(); n++)
    Object value = tmp.get(n);
    data[m][n] = value;
    public int getColumnCount()
    return columnNames.length;
    public int getRowCount()
    return data.length;
    public String getColumnName(int col)
    return columnNames[col];
    public Object getValueAt(int row, int col)
    return data[row][col];
    public boolean isCellEditable(int row, int col)
    if (col < 3)
    return false;
    else if (col == 3)
    return true;
    else
    return false;
    public void setValueAt(Object value, int row, int col)
    data[row][col] = value;
    fireTableCellUpdated(row, col);
    if(col == 3)
    try
    String str = (String)data[row][col];
    data[row][col+1] = new Double( ((Float)data[row][col-2]).doubleValue() * Double.valueOf(str).doubleValue() );
    fireTableCellUpdated(row, col+1);
    totalCost = 0.0;
    for (int k=0; k<TableDemo.costTable.getRowCount(); k++)
    totalCost = totalCost + ((Double)data[k][4]).doubleValue();
    data[TableDemo.costTable.getRowCount() - 1][4] = new Double (totalCost);
    fireTableCellUpdated(TableDemo.costTable.getRowCount() - 1, 4);
    catch(Exception ex)
    System.out.println("Exception caught in MyTableModel class: INVALID INPUT " + ex.getMessage());
    System.out.println(":-(");
    }

    could it possibly be that:
    DefaultTableModel has a vector for the data. You're trying to implement some methods that use your Object[][] but the DefaultTableModel methods want to use the vector that it supplies.

  • Using DefaultTableModel features

    I have my data model which I pass to AbstractTableModel and wrote my own implementation of getValueAt() method.
    I want to use the features provided by DefaultTableModel; for Eg addRows(), moveRows() rotate() etc.
    But defaultTableModel Treats Vector as its DataObject. In my case its different.
    What is the best way to use features of DefaultTableModel.
    TIA
    Zoha.

    What is the best way to use features of DefaultTableModel.Create a DefaultTableModel or extend the DefaultTableModel.
    If you are extending AbstractTableModel then you can't use the methods of DefaultTableModel, you have to write your own. Look at the DefaultTableModel source code for an idea of how to implement the methods. If you model doesn't use Vectors then you need to write your own routing to insert/remove rows of data from the TableModel.

  • Drag n Drop in JTable with AbstractTableModel

    Dear Experts,
    I would like to drag and drop rows in a JTable. For example, if I have 6 rows in a JTable based on an AbstractTableModel and if I am trying to drag row number 5 and wish to drop it at row number 2, then the 5th row which was dragged should be pasted as 3rd row and the rows 3 and 4 should be rearranged (ie, moved one place down).
    Can anyone help me in achieving this? Any readymade code available? :-)
    I tried running the code in the Java Tutorial in the link
    http://java.sun.com/docs/books/tutorial/uiswing/examples/dnd/index.html
    but, this didnt help as it was mainly for a DefaultTableModel I guess. Also, when I used the StringTransferHandler and TableTransferHandler, I was able achieve just copying the dragged row and pasting at the dropped row. The row rearrangement was not functioning.
    Pls Help...
    Thanks & Regards
    Irfaan

    I have 6 rows in a JTable based on an AbstractTableModelDo you know what "Abstract" means? I suggest you look it up in your Java text book.
    You are not using the AbstractTableModel, you are using a TableModel that extends AbstractTableModel.
    but, this didnt help as it was mainly for a DefaultTableModel That is exactly why you should be using the DefaultTableModel since it supports the concept of moving rows. If you want to use a custom TableModel, then you need to implement the concept of moving rows yourself. So why write a custom TableModel when this has already been done for you??

  • What is wrong about this DefaultTableModel code?

    Hi,
    Can anybody tell me what is wrong about the construction of my JTable. I create the instance of the below class and add to my JTable:
    MyTableModel myModel = new MyTableModel();
    JTable costTable = new JTable(myModel);
    I can see printouts "MTM_1,2,3,4" then it gives me an exception
    Exception caught in Scenegraph: 16 >= 16
    The vector IFC_Tree.totalVector has members like:
    IFC_Tree.totalVector[0]: [IFCBeam, 4.962499618530273, m3, 0.0, 0.0]
    IFC_Tree.totalVector[1]: [IFCColumn, 13.84760570526123, m3, 0.0, 0.0]
    IFC_Tree.totalVector[2]: [IFCFloor, 113.82814025878906, m3, 0.0, 0.0]
    IFC_Tree.totalVector[3]: [IFCWall, 229.7195587158203, m3, 0.0, 0.0]
    IFC_Tree.totalVector[4]: [IFCRoofSlab, 215.8400421142578, m2, 0.0, 0.0]
    IFC_Tree.totalVector[5]: [IFCWindow_2.375*2.45, 8.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[6]: [IFCWindow_0.6*0.6, 20.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[7]: [IFCWindow_3.85*2.45, 3.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[8]: [IFCWindow_2.0*2.1, 2.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[9]: [IFCDoor_0.9*2.1, 17.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[10]: [IFCDoor_1.8*2.45, 2.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[11]: [IFCDoor_0.8*2.1, 28.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[12]: [IFCDoor_0.9*2.45, 11.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[13]: [IFCDoor_2.0*2.1, 2.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[14]: [IFCDoor_1.0*2.1, 4.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[15]: [null, null, null, TOTAL COST, 0.0]
    import javax.swing.JTable;
    import javax.swing.table.AbstractTableModel;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.JScrollPane;
    import javax.swing.JFrame;
    import javax.swing.SwingUtilities;
    import javax.swing.JOptionPane;
    import java.awt.*;
    import java.awt.event.*;
    import java.lang.*;
    import javax.swing.DefaultCellEditor;
    import java.util.Vector;
    //public class MyTableModel extends AbstractTableModel
    public class MyTableModel extends DefaultTableModel
    private boolean DEBUG = true;
    static double totalCost = 0.0;
    static Vector data = new Vector();
    static Vector columnNames = new Vector();
    static Vector tmp;
    public MyTableModel()
    System.out.println("MTM_1");
    addColumn("IFCOBJECTS OR PROCESSES");
    addColumn("QUANTITY");
    addColumn("UNITS");
    addColumn("UNIT COST (�)");
    addColumn("TOTAL COST (�)");
    System.out.println("MTM_2");
    for(int i=0; i < IFC_Tree.totalVector.size(); i++)
    System.out.println("MTM_3");
    tmp = (Vector)(IFC_Tree.totalVector.elementAt(i));
    System.out.println("MTM_4");
    addRow(tmp);
    System.out.println("MTM_5");
    System.out.println("MTM_6");
    public int getColumnCount()
    return columnNames.size();
    public int getRowCount()
    public String getColumnName(int col)
    public Object getValueAt(int row, int col)
    public boolean isCellEditable(int row, int col)
    public void setValueAt(Object value, int row, int col)
    }

    Hi,
    Can anybody tell me what is wrong about the construction of my JTable. I create the instance of the below class and add to my JTable:
    MyTableModel myModel = new MyTableModel();
    JTable costTable = new JTable(myModel);
    I can see printouts "MTM_1,2,3,4" then it gives me an exception
    Exception caught in Scenegraph: 16 >= 16
    The vector IFC_Tree.totalVector has members like:
    IFC_Tree.totalVector[0]: [IFCBeam, 4.962499618530273, m3, 0.0, 0.0]
    IFC_Tree.totalVector[1]: [IFCColumn, 13.84760570526123, m3, 0.0, 0.0]
    IFC_Tree.totalVector[2]: [IFCFloor, 113.82814025878906, m3, 0.0, 0.0]
    IFC_Tree.totalVector[3]: [IFCWall, 229.7195587158203, m3, 0.0, 0.0]
    IFC_Tree.totalVector[4]: [IFCRoofSlab, 215.8400421142578, m2, 0.0, 0.0]
    IFC_Tree.totalVector[5]: [IFCWindow_2.375*2.45, 8.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[6]: [IFCWindow_0.6*0.6, 20.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[7]: [IFCWindow_3.85*2.45, 3.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[8]: [IFCWindow_2.0*2.1, 2.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[9]: [IFCDoor_0.9*2.1, 17.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[10]: [IFCDoor_1.8*2.45, 2.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[11]: [IFCDoor_0.8*2.1, 28.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[12]: [IFCDoor_0.9*2.45, 11.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[13]: [IFCDoor_2.0*2.1, 2.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[14]: [IFCDoor_1.0*2.1, 4.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[15]: [null, null, null, TOTAL COST, 0.0]
    import javax.swing.JTable;
    import javax.swing.table.AbstractTableModel;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.JScrollPane;
    import javax.swing.JFrame;
    import javax.swing.SwingUtilities;
    import javax.swing.JOptionPane;
    import java.awt.*;
    import java.awt.event.*;
    import java.lang.*;
    import javax.swing.DefaultCellEditor;
    import java.util.Vector;
    //public class MyTableModel extends AbstractTableModel
    public class MyTableModel extends DefaultTableModel
    private boolean DEBUG = true;
    static double totalCost = 0.0;
    static Vector data = new Vector();
    static Vector columnNames = new Vector();
    static Vector tmp;
    public MyTableModel()
    System.out.println("MTM_1");
    addColumn("IFCOBJECTS OR PROCESSES");
    addColumn("QUANTITY");
    addColumn("UNITS");
    addColumn("UNIT COST (�)");
    addColumn("TOTAL COST (�)");
    System.out.println("MTM_2");
    for(int i=0; i < IFC_Tree.totalVector.size(); i++)
    System.out.println("MTM_3");
    tmp = (Vector)(IFC_Tree.totalVector.elementAt(i));
    System.out.println("MTM_4");
    addRow(tmp);
    System.out.println("MTM_5");
    System.out.println("MTM_6");
    public int getColumnCount()
    return columnNames.size();
    public int getRowCount()
    public String getColumnName(int col)
    public Object getValueAt(int row, int col)
    public boolean isCellEditable(int row, int col)
    public void setValueAt(Object value, int row, int col)
    }

  • I am going nuts Please help me with DefaultTableModel

    Hi al
    Can someone please help me
    I am using jbuilder 10 and running on a Mac.
    I am trying to use DefaultTableModel with this code
    DefaultTableModel tableModel = new DefaultTableModel();
    And I am getting this
    "IND_Client.java": cannot resolve symbol: class DefaultTableModel in class new_efi_database.IND_Client at line 27, column 4
    What am I missing ??
    I can not find out any info on this
    Craig

    have you imported javax.swing.table.* ?
    Also - depending on how much customization you're after consider extending AbstractTableModel......

  • Updating a JTable when using an AbstractTableModel

    Hi,
    I have tried to create a JTable with an AbstractTableModel but I am obviously missing something in all the tutorials and examples as I cannot get the table to update when using my model.
    My application reads data in from a CSV file that is selectable at run time, but I have written a small app that demonstrates the problem I am having.
    If you uncomment the DefaultTableModel lines of code all is OK, but I need to use my Abstract Class as I intend to colour certain rows and add a Boolean column, that I would like to display as a CheckBox and not just the String representation.
    Any help would be great as I am tearing my hair out here!!
    My Test Class
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.table.*;
    import java.util.*;
    public class TestTable extends JFrame implements ActionListener
    private JPanel jpTestTable = new JPanel();          
    private Vector vColumnNames = new Vector();
    private Vector vCellValues = new Vector();
    private DefaultTableModel dtmTestTable;
    private CustomTableModel ctmTestTable;
    private JTable jtTestTable;
    private JScrollPane jspTestTable;
    private JButton jbGo = new JButton();
         public TestTable()
         dtmTestTable = new DefaultTableModel();
         ctmTestTable = new CustomTableModel();
         //jtTestTable = new JTable( dtmTestTable );  //using this instead of my CustomModel works fine
         jtTestTable = new JTable( ctmTestTable );
         jtTestTable.setAutoCreateRowSorter(true);
         jtTestTable.setFillsViewportHeight( true );
         jspTestTable = new JScrollPane( jtTestTable, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS ,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER );
         jspTestTable.setBounds( 10, 10, 350, 400 );
         jspTestTable.setBorder( BorderFactory.createLoweredBevelBorder() );
         jbGo.setText( "Go" );
         jbGo.setBorder( BorderFactory.createRaisedBevelBorder() );
         jbGo.setBounds( 125, 430, 100, 25 );
         jbGo.addActionListener(this);
         jpTestTable.setLayout( null );
         jpTestTable.setBounds( 0, 0, 375, 500 );     
         jpTestTable.add( jspTestTable );
         jpTestTable.add( jbGo );
         this.setTitle( "Test Table" );
         this.getContentPane().setLayout( null );
         this.setBounds( 200, 50, 375, 500 );
         this.getContentPane().add( jpTestTable );
         this.setResizable( false );
         public void actionPerformed( ActionEvent e )
         updateTable();
         public void updateTable()
         vColumnNames.add( "Please" );
         vColumnNames.add( "work" );
         vColumnNames.add( "you" );
         vColumnNames.add( "git!" );
         vColumnNames.trimToSize();
         Vector vRow = new Vector();
              for( int i = 0; i < 10; i++ )
                   for( int x = 0; x < vColumnNames.size(); x++ )
                        vRow.add( "" + i + "" + x );
              vCellValues.add( vRow );
         //dtmTestTable.setDataVector( vCellValues, vColumnNames );  //using this instead of my CustomModel works fine
         ctmTestTable.setDataVector( vCellValues, vColumnNames );
         public void processWindowEvent(WindowEvent e)
         super.processWindowEvent(e);
              if(e.getID() == WindowEvent.WINDOW_CLOSING)
              exit();
         public void exit()
         System.exit( 0 );     
         public static void main(String args[])
         TestTable tt = new TestTable();
         tt.setVisible( true );
    }And my CustomTableModel Class
    import javax.swing.*;
    import javax.swing.table.*;
    import java.awt.*;
    import java.util.*;
    public class CustomTableModel extends AbstractTableModel
    protected Vector columnIdentifiers  = new Vector();
    protected Vector dataVector = new Vector();
         public CustomTableModel()
         public CustomTableModel( Vector data, Vector columnNames )
         setDataVector( data, columnNames );
         public int getColumnCount()
         return columnIdentifiers.size();
         public int getRowCount()
         return dataVector.size();
         public String getColumnName( int col )
         return "" + columnIdentifiers.get( col );
         public Object getValueAt( int row, int col )
         Vector vRow = new Vector();
         vRow = (Vector) dataVector.get( row );
         return (Object) vRow.get( col );
         public Class getColumnClass(int c)
         return getValueAt(0, c).getClass();
         public boolean isCellEditable(int row, int col)
              if (col < 2)
                   return false;
              else
                   return true;
         public void setValueAt( Object value, int row, int col )
         Vector vTemp = (Vector) dataVector.get( row );
         Vector<Object> vRow = new Vector<Object>();
              for( int i = 0; i < vTemp.size(); i++ )
                   vRow.add( (Object) vTemp.get( i ) );
         vRow.remove( col );
         vRow.add( col, value );
         vRow.trimToSize();     
         dataVector.remove( row );
         dataVector.add( row, vRow );
         dataVector.trimToSize();
         fireTableCellUpdated(row, col);
         public void setDataVector( Vector data, Vector columnNames )
         columnIdentifiers  = (Vector) columnNames.clone();
         dataVector = (Vector) data.clone();
         fireTableDataChanged();
    }I have just tried adding the following code after reading another example, but same result - arrrrrrrgggggggghhhhhhhhh!!!!
    ctmTestTable = (CustomTableModel) jtTestTable.getModel();
    ctmTestTable.fireTableDataChanged();Edited by: Mr_Bump180 on Jul 28, 2008 2:51 PM

    Hi camickr,
    Well that is good news as my Abstact class is about as much good as an ashtray on a motorbike. I think I must have misread or misunderstood the Table Tutorials as I thought I had to use an Abstrat class to get colurs based on conditions and to get Check Boxes to represent Boolean variables.
    I am clearly struggling with this concept - which I have never used before - do you know of any tutorials, that explain how to update a JTable with file data at runtime, as all the ones I have looked at set it as part of the java code - which is no good to me.
    Also am I overriding the DefaultTableModel Class correctly - I have written a seperate Model class but wounder if I need to include it in with my JTable class. I was trying to make it generic so I didn't have to write one for each JTable - but as I can't get it to work I should perhaps try to walk before I run.
    I'm not asking for the code, but just a guide to how close I am to where I want to be, and some links to tutorials that are closer to what I want to achieve. I will reread the Java Table Tutorial tonight - and you never know the penny may drop all on it's own this time!!!
    Thanks

  • Help needed about DefaultTableModel code

    Hi,
    Can anybody tell me what is wrong about the construction of my JTable. I create the instance of the below class and add to my JTable:
    MyTableModel myModel = new MyTableModel();
    JTable costTable = new JTable(myModel);
    I can see printouts "MTM_1,2,3,4" then it gives me an exception
    Exception caught in Scenegraph: 16 >= 16
    The vector IFC_Tree.totalVector has members like:
    IFC_Tree.totalVector[0]: [IFCBeam, 4.962499618530273, m3, 0.0, 0.0]
    IFC_Tree.totalVector[1]: [IFCColumn, 13.84760570526123, m3, 0.0, 0.0]
    IFC_Tree.totalVector[2]: [IFCFloor, 113.82814025878906, m3, 0.0, 0.0]
    IFC_Tree.totalVector[3]: [IFCWall, 229.7195587158203, m3, 0.0, 0.0]
    IFC_Tree.totalVector[4]: [IFCRoofSlab, 215.8400421142578, m2, 0.0, 0.0]
    IFC_Tree.totalVector[5]: [IFCWindow_2.375*2.45, 8.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[6]: [IFCWindow_0.6*0.6, 20.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[7]: [IFCWindow_3.85*2.45, 3.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[8]: [IFCWindow_2.0*2.1, 2.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[9]: [IFCDoor_0.9*2.1, 17.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[10]: [IFCDoor_1.8*2.45, 2.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[11]: [IFCDoor_0.8*2.1, 28.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[12]: [IFCDoor_0.9*2.45, 11.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[13]: [IFCDoor_2.0*2.1, 2.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[14]: [IFCDoor_1.0*2.1, 4.0, number, 0.0, 0.0]
    IFC_Tree.totalVector[15]: [null, null, null, TOTAL COST, 0.0]
    import javax.swing.JTable;
    import javax.swing.table.AbstractTableModel;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.JScrollPane;
    import javax.swing.JFrame;
    import javax.swing.SwingUtilities;
    import javax.swing.JOptionPane;
    import java.awt.*;
    import java.awt.event.*;
    import java.lang.*;
    import javax.swing.DefaultCellEditor;
    import java.util.Vector;
    //public class MyTableModel extends AbstractTableModel
    public class MyTableModel extends DefaultTableModel
    private boolean DEBUG = true;
    static double totalCost = 0.0;
    static Vector data = new Vector();
    static Vector columnNames = new Vector();
    static Vector tmp;
    public MyTableModel()
    System.out.println("MTM_1");
    addColumn("IFCOBJECTS OR PROCESSES");
    addColumn("QUANTITY");
    addColumn("UNITS");
    addColumn("UNIT COST (�)");
    addColumn("TOTAL COST (�)");
    System.out.println("MTM_2");
    for(int i=0; i < IFC_Tree.totalVector.size(); i++)
    System.out.println("MTM_3");
    tmp = (Vector)(IFC_Tree.totalVector.elementAt(i));
    System.out.println("MTM_4");
    addRow(tmp);
    System.out.println("MTM_5");
    System.out.println("MTM_6");
    public int getColumnCount()
    return columnNames.size();
    public int getRowCount()
    public String getColumnName(int col)
    public Object getValueAt(int row, int col)
    public boolean isCellEditable(int row, int col)
    public void setValueAt(Object value, int row, int col)
    }

    I don't understand why you override the methods getRowCount() ... and why there are the static member variables columnNames .... (all this is done by the DefaultTableModel). Your table model initialization in the constructor should suffice.
    Pierre

Maybe you are looking for