简体   繁体   中英

How to add rows to JTable with AbstractTableModel method?

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;
    }
}

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;
   }

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM