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;
}
}
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 anArrayList<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.Since you try to make your own
myAbstractTableModel
, you should extends AbstractTableModel rather than a concrete implementation likeDefaultTableModel
. 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
Just make