简体   繁体   English

如何使用AbstractTableModel方法向JTable添加行?

[英]How to add rows to JTable with AbstractTableModel method?

I want to add rows to an already initialized JTable. 我想向已初始化的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 每当我尝试运行程序时,都会收到NullPointerException以及

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). 我试图使用ArrayList作为存储数据的地方...但是然后,在下面的注释中标记了“ cols-rows-issue” ...找不到数组值(因为我现在使用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: sscce类:

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: DataStore类:

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 . 由于尝试创建自己的myAbstractTableModel ,因此应该扩展AbstractTableModel而不是像DefaultTableModel这样的具体实现。 Use an ArrayList to store your Data Objects. 使用ArrayList来存储您的数据对象。 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). 我试图使用ArrayList作为存储数据的地方...但是然后,在下面的注释中标记了“ cols-rows-issue” ...找不到数组值(因为我现在使用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. 您将需要从ArrayList中提取数据。 If you are unfamiliar with ArrayList methods, then please check out the ArrayList API . 如果您不熟悉ArrayList方法,请查看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. 主要是您试图将ArrayList视为数组,当然不是,因此,使用array.length或使用数组索引(array [i] [j])的数组类型构造将惨遭失败。 Again, please look at the ArrayList API linked to above or a decent ArrayList tutorial to find out how to use these guys. 再次,请查看上面链接的ArrayList API或一个不错的ArrayList教程,以了解如何使用这些工具。 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. 例如,如果编译器告诉您ArrayList没有length属性或方法,则在ArrayList API中查找获取所需信息的适当方法。 That's what the API is for. 这就是API的目的。

Also, your ArrayList should not hold Object, in other words it shouldn't be ArrayList<Object> but should be much more specific. 同样,您的ArrayList不应包含Object,换句话说,它不应为ArrayList<Object>而应更加具体。 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> . 因此,如果我们调用包含每一行数据RowData的类,则将ArrayList<RowData>声明为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. 因此,要在col的行中获取值,您需要从模型的ArrayList中提取行索引的RowData(假设这是行数据的类的名称),然后调用对象的getter方法以提取col索引关联的项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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