Overriding getValueAt() in AbstractTableModel to handle null values

Hi,

Anyone know what the correct method is of implementing getValueAt() when you create a class that inherits from AbstractTableModel such that it returns an appropriate value when the value asked for does not exist (i.e. is null)?

Cheers,
Steve
LVL 5
steve_bagnallAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

CEHJCommented:
You don't necessarily need to override anything to do that - depends on what you want to do - tell us more ;-)
0
CEHJCommented:
e.g. you could do this:


String s = (String)model.getValueAt(x, y);
if (s == null) {
      s = "";
}
0
durgaprasad_jCommented:
hi,
try something like this

String getValueAt(int x, int y)
{
       String s=super.getValueAt(x,y);
        if(s==null)
             s="";
        return s;
}

DP
0
Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

steve_bagnallAuthor Commented:
Thanks CEHJ,

Heres more ... the method addToSearchResults() in my GUI class that calls setValueAt() on a SearchResults object (jtResults) which extends JPanel (used within the GUI JFrame) and has an inner class which extends AbstractTableModel (I have included the code for both below).  

The initial error I get when I try to add a new row to the table is ...

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: java.lang.Object

Following this I get a whole load of javax.swing exceptions which I think are due to the JFrame does not refresh properly.

If I alt-tab and force a screen refresh by covering the JFrame with another application then reveiling it again, you can see that is has sort of worked, it shows the search results in the table along with a row of [object-references] which is expected.  

I have done what you have said before and returned a new String("<NULL>") and again this works except for all the javax.swing. exceptions causing the screen to not display properly.  Any ideas?

Cheers,
Steve


GUI CALLING METHOD================

public void addToSearchResults(Retailer obj) {

   jtResults.setValueAt(obj.getName(), rowsShowing, 0);
   jtResults.setValueAt(obj.getCategory(), rowsShowing, 1);
   jtResults.setValueAt(obj.getType(), rowsShowing, 2);

   rowsShowing++;

}



CLASS SearchResults ================

package churchillchina.gapanalysis;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.AbstractTableModel;
import java.awt.Dimension;
import java.awt.GridLayout;

import java.util.*;

class SearchResults extends JPanel {

      private static GapLogger logger;

      public String toString(){
            StringBuffer sb = new StringBuffer();
            sb.append(getClass().getName());
            sb.append(" table=[").append(this.table).append("]");
            sb.append(" model=[").append(this.model).append("]");
            return sb.toString();
      }


      private JTable table;
      private MyTableModel model;

    public SearchResults(Vector<Vector<Object>>objArray, Vector<String>colNames) {
        super(new GridLayout(1,0));

        logger = new GapLogger();




            model = new MyTableModel(objArray, colNames);
        table = new JTable(objArray, colNames);
        table.setModel(model);

        //Create the scroll pane and add the table to it.
        JScrollPane scrollPane = new JScrollPane(table);

        //Add the scroll pane to this panel.
        add(scrollPane);
    }


    public void setThinCol(int col) {



            TableColumn column = null;

            for (int i = 0; i < table.getColumnCount(); i++) {
                column = table.getColumnModel().getColumn(i);

                if (i == col) {
                    column.setMinWidth(7);
                        column.setPreferredWidth(17);
                        column.setMaxWidth(170);

                } else {

                        column.setMinWidth(15);
                        column.setPreferredWidth(150);
                        column.setMaxWidth(1500);

                }
            }
      }

      public void setValueAt(Object obj, int row, int col) {

            table.setValueAt(obj, row, col);
      }


      public int getColumnCount() {
            return table.getColumnCount();
      }


      public void addRow() {

            model.addRow();
      }




    class MyTableModel extends AbstractTableModel {



        private Vector<String> columnNames;
        private Vector<Vector<Object>> data;

        private int noOfRows;


        public MyTableModel(Vector<Vector<Object>> objArray, Vector<String> colNames) {


                  columnNames = new Vector<String>();

                  columnNames.setSize(colNames.size());

                  for (int row = 0; row < colNames.size(); row++) {

                        columnNames.set(row,  colNames.elementAt(row));
                  }


                  data = new Vector<Vector<Object>>();

                  data.setSize(objArray.size());


                  for (int row = 0; row < objArray.size(); row++) {

                        data.set(row, new Vector<Object>());
                        data.elementAt(row).setSize(objArray.elementAt(row).size());

                        for (int col = 0; col < objArray.elementAt(row).size(); col++) {
                              data.elementAt(row).set(col, objArray.elementAt(row).elementAt(col));
                        }
                  }




            }


        public int getColumnCount() {
            return columnNames.size();
        }

        public int getRowCount() {
            if (data != null) {
                  return data.size();
                  } else {
                        return 0;
                  }
        }

        public String getColumnName(int col) {
            return columnNames.elementAt(col);
        }

        public Object getValueAt(int row, int col) {

                  logger.log("testing");


                  if ( (row < noOfRows) && (col < columnNames.size()) ) {

                        return data.elementAt(row).elementAt(col);
                  } else {

                        return new Object();
                  }


            }

        /*
         * JTable uses this method to determine the default renderer/
         * editor for each cell.  If we didn't implement this method,
         * then the last column would contain text ("true"/"false"),
         * rather than a check box.
         */
        public Class getColumnClass(int c) {
            return getValueAt(0, c).getClass();
        }

        /*
         * Don't need to implement this method unless your table's
         * editable.
         */
        public boolean isCellEditable(int row, int col) {
            //Note that the data/cell address is constant,
            //no matter where the cell appears onscreen.

            if (col == getColumnCount() - 1) {
                        return true;
                  } else {
                          return false;
                  }
              }

        /*
         * Don't need to implement this method unless your table's
         * data can change.
         */
        public void setValueAt(Object value, int row, int col) {


                  if (row >= noOfRows) {
                        data.add(new Vector<Object>());

                        for (int i = 0; i < columnNames.size(); i++) {
                              data.elementAt(row).add(new Object());
                        }

                        noOfRows++;
                  }

            data.elementAt(row).set(col, value);


            // not needed unless listeners registered
            fireTableDataChanged();

        }


        public void addRow() {

                  for (int col = 0; col < columnNames.size(); col++) {
                        setValueAt("", noOfRows, col);
                  }
                  noOfRows ++;

            }


    }


}
0
CEHJCommented:
Firstly i'm wondering why you're using that custom table model when you could simply use an AbstractTableModel?
0
steve_bagnallAuthor Commented:
CEHJ,

Not sure what you mean - if I comment out my implementation of setValueAt(), nothing happens when I try and add a row.  MyTableModel extends AbstractTableModel in the code above if you missed that?

Cheers,
Steve
0
CEHJCommented:
>>Firstly i'm wondering why you're using that custom table model when you could simply use an AbstractTableModel?

Oops, the above should have said:

Firstly i'm wondering why you're using that custom table model when you could simply use a DefaultTableModel?
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
steve_bagnallAuthor Commented:
CEHJ,

That'll do .. Cheers!
0
CEHJCommented:
:-)
0
objectsCommented:
> Firstly i'm wondering why you're using that custom table model when you could simply use a DefaultTableModel?

Because it provides a far cleaner solution.
0
steve_bagnallAuthor Commented:
objects, for now the default table works fine for me - if later I find it doesn't then look out for my post in a few days :)
0
objectsCommented:
Will keep an eye out for it :)
0
CEHJCommented:
>>Because it provides a far cleaner solution.

Why?
0
CEHJCommented:
:-)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.