?
Solved

Overriding getValueAt() in AbstractTableModel to handle null values

Posted on 2005-03-07
14
Medium Priority
?
1,253 Views
Last Modified: 2012-06-27
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
0
Comment
Question by:steve_bagnall
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 4
  • 2
  • +1
14 Comments
 
LVL 86

Expert Comment

by:CEHJ
ID: 13475436
You don't necessarily need to override anything to do that - depends on what you want to do - tell us more ;-)
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 13475455
e.g. you could do this:


String s = (String)model.getValueAt(x, y);
if (s == null) {
      s = "";
}
0
 
LVL 6

Expert Comment

by:durgaprasad_j
ID: 13475636
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 5

Author Comment

by:steve_bagnall
ID: 13475644
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
 
LVL 86

Expert Comment

by:CEHJ
ID: 13475717
Firstly i'm wondering why you're using that custom table model when you could simply use an AbstractTableModel?
0
 
LVL 5

Author Comment

by:steve_bagnall
ID: 13475743
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
 
LVL 86

Accepted Solution

by:
CEHJ earned 2000 total points
ID: 13475924
>>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
 
LVL 5

Author Comment

by:steve_bagnall
ID: 13476504
CEHJ,

That'll do .. Cheers!
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 13476524
:-)
0
 
LVL 92

Expert Comment

by:objects
ID: 13481234
> 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
 
LVL 5

Author Comment

by:steve_bagnall
ID: 13484306
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
 
LVL 92

Expert Comment

by:objects
ID: 13484310
Will keep an eye out for it :)
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 13486249
>>Because it provides a far cleaner solution.

Why?
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 13498298
:-)
0

Featured Post

[Webinar] How Hackers Steal Your Credentials

Do You Know How Hackers Steal Your Credentials? Join us and Skyport Systems to learn how hackers steal your credentials and why Active Directory must be secure to stop them.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

INTRODUCTION Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.   However, when your application has vi…
Are you developing a Java application and want to create Excel Spreadsheets? You have come to the right place, this article will describe how you can create Excel Spreadsheets from a Java Application. For the purposes of this article, I will be u…
Viewers learn how to read error messages and identify possible mistakes that could cause hours of frustration. Coding is as much about debugging your code as it is about writing it. Define Error Message: Line Numbers: Type of Error: Break Down…
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.
Suggested Courses
Course of the Month9 days, 3 hours left to enroll

764 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question