2

I want to add rows to an already initialized JTable. Apart from other elements I have the following (relevant) code:

import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

class sscce extends JFrame {

private static final long serialVersionUID = 1L;    // Serial ID...

// Interface-Elemente erzeugen
Container content = getContentPane();

DefaultTableModel myAbstractTableModel = new DefaultTableModel () {
    private static final long serialVersionUID = 1L;    // whatever
    public String[] columnNames = {"AuftragNr", "Datum & Uhrzeit", "Von", "Nach", "erledigt?"};
    public Object[][] data = {{"156", "31.12.2012 - 10:39:31", "5/5", "205/39", 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 getValueAt(0, c).getClass();
    }

    public boolean isCellEditable(int row, int col) {
        if (col != 4) {
            return false;
        } else {
            return true;
        }
    }

    public void setValueAt(Object value, int row, int col) {
        data[row][col] = value;
        fireTableCellUpdated(row, col);
    }
};

JTable auftragTable = new JTable(myAbstractTableModel);
JScrollPane tableScrollPane = new JScrollPane(auftragTable);
JButton auftragAenderungSpeichern = new JButton("speichern");

public sscce() {
    setTitle("Auftragsverwaltung");
    setSize(700, 500);
    setLocation(500, 200);
    setLayout(null);
    setResizable(false);
    tableScrollPane.setBounds(50, 50, 500, 200);

    addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent e) {
            System.exit(0);
        }
    });
}

public void actionPerformed(ActionEvent e) {

}

@SuppressWarnings("deprecation")
public static void main(String[] args) {
    JFrame f = new sscce();
    f.show();
}
}

Whenever I try to running the progam, I get a NullPointerException along with

at javax.swing.table.DefaultTableModel.setDataVector(Unknown Source)
at javax.swing.table.DefaultTableModel.<init>(Unknown Source)
at javax.swing.table.DefaultTableModel.<init>(Unknown Source)
at javax.swing.table.DefaultTableModel.<init>(Unknown Source)

for the following line of code:

public int getRowCount() {
    return data.length;
}

Why is that? What's wrong with my code? Shouldn't the program be able to "find" data?


EDIT: Second approach

I tried to use an ArrayList as a place for the storage of data... but then there's the 'cols-rows-issue' as marked in the comments below... The array values cannot be found (as I now use an ArrayList). How can I solve that?

import java.awt.Container;
import java.awt.List;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

class sscce extends JFrame {

private static final long serialVersionUID = 1L;    // Serial ID...

Container content = getContentPane();

AbstractTableModel myAbstractTableModel = new AbstractTableModel () {
    private static final long serialVersionUID = 1L;    // whatever
    private String[] columnNames = {"AuftragNr", "Datum & Uhrzeit", "Von", "Nach", "erledigt?"};
    private ArrayList<Object> data = new ArrayList<Object>();


    public void addRow(List rowData) {
        data.add(rowData);
        fireTableRowsInserted(data.size() - 1, data.size() - 1);
    }
    public int getColumnCount() {
        return columnNames.length;
    }

    public int getRowCount() {
        return data.length;
        // can be solved via .size();
    }

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

    public Object getValueAt(int row, int col) {
        return data[row][col];
        // no idea, how to solve that?!
    }

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

    public boolean isCellEditable(int row, int col) {
        if (col == 4) {
            return true;
        }
        return false;
    }

    public void setValueAt(Object value, int row, int col) {
        data[row][col] = value;
        // same issue here...
        fireTableCellUpdated(row, col);
    }
};

JTable auftragTable = new JTable(myAbstractTableModel);
JScrollPane tableScrollPane = new JScrollPane(auftragTable);
JButton auftragAenderungSpeichern = new JButton("speichern");

public sscce() {
    setTitle("Auftragsverwaltung");
    setSize(700, 500);
    setLocation(500, 200);
    setLayout(null);
    setResizable(false);
    tableScrollPane.setBounds(50, 50, 500, 200);

    addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent e) {
            System.exit(0);
        }
    });
}

@SuppressWarnings("deprecation")
public static void main(String[] args) {
    JFrame f = new sscce();
    f.show();
}
}

EDIT: Third approach

sscce class:

import java.awt.Container;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

class sscce extends JFrame {

    private static final long serialVersionUID = 1L;    // Serial ID...

    Container content = getContentPane();

    AbstractTableModel myAbstractTableModel = new AbstractTableModel() {
        private static final long serialVersionUID = 1L;    // whatever
        private String[] columnNames = {"AuftragNr", "Datum & Uhrzeit", "Von", "Nach", "erledigt?"};
        private ArrayList<DataStore> data = new ArrayList<DataStore>();


        public void addRow(DataStore rowData) {
            data.add(rowData);
            fireTableRowsInserted(data.size() - 1, data.size() - 1);
        }
        public int getColumnCount() {
            return columnNames.length;
        }

        public int getRowCount() {
            return data.size(); // length
            // can be solved via .size();
        }

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

        public Object getValueAt(int row, int col) {
//          change made here
            DataStore rowElement = data.get(row);
            Object value = rowElement.getItemOnPosition(col);
            return value;
        }

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

        public boolean isCellEditable(int row, int col) {
            if (col == 4) {
                return true;
            }
            return false;
        }

        public void setValueAt(Object value, int row, int col) {
            // change made here
            DataStore rowElement = data.get(row);
            rowElement.setItemOnPosition(col, value);
            fireTableCellUpdated(row, col);
        }
    };

    JTable auftragTable = new JTable(myAbstractTableModel);
    JScrollPane tableScrollPane = new JScrollPane(auftragTable);
    JButton auftragAenderungSpeichern = new JButton("speichern");

    public sscce() {
        setTitle("Auftragsverwaltung");
        setSize(700, 500);
        setLocation(500, 200);
        setLayout(null);
        setResizable(false);
        tableScrollPane.setBounds(50, 50, 500, 200);

        content.add(tableScrollPane);

        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }

    @SuppressWarnings("deprecation")
    public static void main(String[] args) {
        JFrame f = new sscce();
        f.show();
    }
}

DataStore class:

public class DataStore {

    Integer auftragNr;
    String datumUhrzeit;
    String von;
    String nach;
    Boolean status;

    public DataStore(Integer a, String b, String c, String d, Boolean e) {
        auftragNr = a;
        datumUhrzeit = b;
        von = c;
        nach = d;
        status = e;
    }

    public Object getItemOnPosition(int pos) {
        if(pos == 1) {
            return (Integer) auftragNr;
        }
        if(pos == 2) {
            return datumUhrzeit;
        }
        if(pos == 3) {
            return von;
        }
        if(pos == 4) {
            return nach;
        }
        if(pos == 5) {
            return (Boolean) status;
        }
        return null;
    }

    public Object setItemOnPosition(int pos, Object newValue) {
        if(pos == 1) {
            auftragNr = (Integer) newValue;
        }
        if(pos == 2) {
            datumUhrzeit = (String) newValue;
        }
        if(pos == 3) {
            von = (String) newValue;
        }
        if(pos == 4) {
            nach = (String) newValue;
        }
        if(pos == 5) {
            status = (Boolean) newValue;
        }
        return null;
    }
}
Stefan Surkamp
  • 972
  • 1
  • 16
  • 31

2 Answers2

3

Since you try to make your own myAbstractTableModel, you should extends AbstractTableModel rather than a concrete implementation like DefaultTableModel. Use an ArrayList to store your Data Objects.How to Use Tables shows you the basics of how to do this.

By the way, makes your fields the most less visibility possible if there is no reason to be.

Also

public boolean isCellEditable(int row, int col) {
        if (col != 4) {
            return false;
        } else {
            return true;
        }
    }

Just make

public boolean isCellEditable(int row, int col) {
        return col == 4;
   }
nachokk
  • 14,363
  • 4
  • 24
  • 53
  • Thanks for your reply. How can I do this? Do I have to add a new class? – Stefan Surkamp Jul 14 '13 at 19:34
  • 1
    you already making a new class (anonymous class) you can make your own class if you are gonna to use in different places or ... as anonymous class like `AbstractTableModel myAbstractTableModel = new AbstractTableModel () { //implements all abstract methods..` – nachokk Jul 14 '13 at 19:38
  • 1
    He'll also need an `addRow(...)` method that calls `fireTableRowsInserted(...)` after adding a row to the model (which probably should be a `List>`). – Hovercraft Full Of Eels Jul 14 '13 at 20:00
  • Okay, I've changed that... but that directly leads me to my initial problem... I want to use * myAbstractTableModel.addRow(new Object[]{"Column 1", "Column 2", "Column 3", "as", false}); * to add rows to the table, which does not work with AbstractTableModels but only DefaultTableModels... Any solution here? – Stefan Surkamp Jul 14 '13 at 20:01
  • @HovercraftFullOfEels: I already had that but somehow it didn't want to accept my way of input... So I tried a workaround as in OP. – Stefan Surkamp Jul 14 '13 at 20:03
  • @HovercraftFullOfEels: Any hints for me how to make a addRow method? I'm desperately trying to solve that for days... – Stefan Surkamp Jul 14 '13 at 22:35
  • @StefanSurkamp: if you've tried something and it doesn't work, then show your attempt as an edit to your original post. Don't delete any part of the original post, but add additional information and code to the bottom. And try to avoid "work arounds". – Hovercraft Full Of Eels Jul 14 '13 at 22:49
  • @HovercraftFullOfEels: Edited my original post. And yes, I'd love to avoid workarounds, if possible :) – Stefan Surkamp Jul 14 '13 at 23:26
2

I tried to use an ArrayList as a place for the storage of data... but then there's the 'cols-rows-issue' as marked in the comments below... The array values cannot be found (as I now use an ArrayList). How can I solve that?

Yes, the array values can't be found because you're not using an array. You will need to extract the data from the ArrayList. If you are unfamiliar with ArrayList methods, then please check out the ArrayList API.

Regarding your code, you have compilation errors, and wherever you find these types of errors, you must look into what you might be doing wrong. Mainly you're trying to treat an ArrayList as if it were an array, which of course it is not, and so array type constructs, using array.length or using array indices (array[i][j]) will fail miserably. Again, please look at the ArrayList API linked to above or a decent ArrayList tutorial to find out how to use these guys. For instance, if the compiler tells you that an ArrayList does not have a length property or method -- then look in the ArrayList API for an appropriate method that gets the information that you want. That's what the API is for.

Also, your ArrayList should not hold Object, in other words it shouldn't be ArrayList<Object> but should be much more specific. Usually a table model's row will hold an object whose properties represent each item of the row. So if we call the class that holds each row's data RowData, your ArrayList would be declared an ArrayList<RowData>. So to get your value at row, col, you'll need to extract the row index's RowData (assuming that this is the name of the row data's class) from your model's ArrayList, and then call the object's getter method to extract the col index-associated item.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • that's why he gets NullPointerException?? – nachokk Jul 14 '13 at 19:21
  • Ahh, I think you got my brain thinking! I was aware of the qualities of arrays/arraylists but somehow I was messing around too long with it to think clearly. One last thing: In the above code everything should be ok ... but I cannot call 'addRow()' in the rest of my code? Am I missing something here again? – Stefan Surkamp Jul 15 '13 at 07:54
  • Would one solution be to not use myAbstractTableModel as an anonymous class but as an actual class instance? Like this I can call *addRow()*... – Stefan Surkamp Jul 15 '13 at 08:09
  • Yup, this is doing it... Any criticism concerning code quality? – Stefan Surkamp Jul 15 '13 at 08:19