3

I'm fighting with a implementation of a jTable. I created my own TableModel class. And there is the problem. Somehow my tableData array (ArrayList of Obejct[]) is not being written correctly. At the end I get a table where all the rows are having the values.

Does anyone see why the ArrayList is not written correctly?

class MyTableModel extends AbstractTableModel {
    private String[] columnNames = {"Auftragsnummer",
                                    "Kunde",
                                    "Kunden Nr.",
                                    "Erfasst",
                                    "Kommt",
                                    "Geht",
                                    "Kommentar"};

    String[] temp_delete = new String[10];
    int index_delete = 0;

    private ArrayList<Object[]> tableData = new ArrayList<Object[]>();

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

    public int getRowCount() {
        return tableData.size();
    }

    public String getColumnName(int col) {
        return columnNames[col];
    }

    public Object getValueAt(int row, int col) {
        Object [] temp = tableData.get(row);

        return temp[col];
    }

    public void removeAllEntry(){
        for (int i = 0; i < tableData.size(); i++) {
            tableData.remove(i);
        }
        model.fireTableDataChanged();
    }

     public Class getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }


    public boolean isCellEditable(int row, int col) {

        switch (col){
            case 4:
                return true;
            default: return false;
        }
    }

     public void addText(Object[] object) {
        tableData.add(object);

       fireTableDataChanged();
      }

}

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
user1511924
  • 53
  • 1
  • 6

2 Answers2

2

The parent implementation of setValueAt() does nothing. You'll need to implement setValueAt() to update your internal data structure, tableData, and fire the appropriate TableModelEvent, which will update your view.

    @Override
    public void setValueAt(Object aValue, int row, int col) {
        ... // update tableData
        this.fireTableCellUpdated(row, col); // notify the view
    }

As an aside, consider List<List<Object>> instead of ArrayList<Object[]>.

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • But do I really need to implement this? I use addText() to insert data into the table. Won't this work? – user1511924 Jul 10 '12 at 06:28
  • Yes. Is there some reason _not_ to do so? `JTable` uses `setValueAt()`; it knows nothing about `addText()`. Does your `addText()` really change _all_ cell values? Wouldn't `fireTableRowsUpdated()` be sufficient? – trashgod Jul 10 '12 at 11:06
  • No there is no reason, you are right. I've implemented the methode and removed the setText() (which I had from an other forum). It works! Brilliant thanks! I'll post the code again in the next answer, for everyone interessted. – user1511924 Jul 10 '12 at 13:11
1

Thanks to trashgod I figured it out (see his post). Working code here:

class MyTableModel extends AbstractTableModel {
    private String[] columnNames = {"Auftragsnummer",
                                    "Kunde",
                                    "Kunden Nr.",
                                    "Erfasst",
                                    "Kommt",
                                    "Geht",
                                    "Kommentar",
                                    "Abteilung"};

    String[] temp_delete = new String[10];
    int index_delete = 0;

   private ArrayList<ArrayList<Object>> tableData = new ArrayList<ArrayList<Object>>();


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

    public int getRowCount() {
        return tableData.size();

    }

    public String getColumnName(int col) {
        return columnNames[col];
    }

    public Object getValueAt(int row, int col) {

        if(tableData.size()> 0){
            return tableData.get(row).get(col);
        }

         return null;
    }

    public void removeAllEntry(){

            tableData.clear();
        model.fireTableDataChanged();
    }

    /*
     * 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) {
        if(tableData.size()> 0){
            return getValueAt(0, c).getClass();
        }

        return String.class;
    }

    /*
     * 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.

        switch (col){
            case 4:
                return true;
            default: 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(tableData.size() <= row){

            ArrayList<Object> arrayList = new ArrayList<Object>();

            for(int i = 0; i < columnNames.length;i++){
                arrayList.add("");
            }

            tableData.add(arrayList);
        }

        ArrayList<Object> object = tableData.get(row);

        object.add(col, value);

        tableData.set(row, object);

        fireTableDataChanged();

    }

}

user1511924
  • 53
  • 1
  • 6
  • Coding to the interface allows one to change the implementation as the need arises, although I'm wary of the need to insert empty rows. – trashgod Jul 10 '12 at 13:46