Не могу разобраться с классом DefaultTableModel

183
30 октября 2018, 05:40

Сама таблица:

import javax.swing.table.DefaultTableModel;
import java.util.ArrayList;
public class TableModel extends DefaultTableModel {
ArrayList<Contact> contacts;

public TableModel(ArrayList<Contact> contacts) {
    this.contacts = contacts;
}
public int returnSize(){
    return contacts.size();
}
public void addNewContact(ArrayList<Contact> contacts){
    contacts.add(new Contact());
    this.contacts=contacts;
}
public void removeContact(ArrayList<Contact> contacts, int row){
    contacts.remove(row);
    removeRow(row);
    this.contacts=contacts;
}
@Override
public int getColumnCount() {
    return 3;
}
public int getRowCount(){
   return returnSize();
}
@Override
public String getColumnName(int column) {
    switch (column) {
        case 0:
            return "Имя";
        case 1:
            return "Фамилия";
        case 2:
            return "Мобильный телефон";
    }
    return "";
}
@Override
public boolean isCellEditable(int row, int column) {
    return true;
}
@Override
public void setValueAt(Object aValue, int row, int column) {
    Contact contact = contacts.get(row);
    switch (column){
        case 0: contact.setFirstName((String) aValue);
        break;
        case 1: contact.setSecondName((String) aValue);
        break;
        case 2: contact.setNumber((String) aValue);
        break;
    }
}
@Override
public Object getValueAt(int row, int column) {
    Contact contact = contacts.get(row);
    switch (column) {
        case 0:
            return contact.getFirstName();
        case 1:
            return contact.getSecondName();
        case 2:
            return contact.getNumber();
    }
        return " ";
    }
    }

Класс с методом main и списком контактов:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.util.ArrayList;
import java.util.Vector;
public class ContactsBook extends JFrame {
ArrayList<Contact> contacts;
TableModel model;
JTable table;

public static void main(String[] args) {
    new ContactsBook().go();
}
ContactsBook(){
    contacts = new ArrayList<Contact>();
}

public void go(){
    System.out.println(contacts);
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    setVisible(true);
    FlowLayout flowLayout = new FlowLayout();
    flowLayout.setHgap(30);
    JPanel panel = new JPanel(flowLayout);
    JButton addBtn = new JButton("Добавить");
    addBtn.addActionListener(new addButtonListener());
    JButton dltBtn = new JButton("Удалить");
    dltBtn.addActionListener(new addDeleteListener());


    panel.add(addBtn);
    panel.add(dltBtn);



    model = new TableModel(contacts);
    System.out.println(model.returnSize());
    table = new JTable(model);
    JScrollPane scroll = new JScrollPane(table);
    scroll.setPreferredSize(new Dimension(400,400));
    add(BorderLayout.CENTER,scroll);
    add(BorderLayout.NORTH,panel);
    pack();

}

public class addButtonListener implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e) {
        int size=contacts.size();
        model.addNewContact(contacts);
        model.addRow(new Object[]{contacts.get(size).getFirstName(),contacts.get(size).getSecondName(),contacts.get(size).getNumber()});
    }
}
public class addDeleteListener implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e) {
        int row = table.getSelectedRow();
        if (row>-1)
        model.removeContact(contacts,row);

    }
}
}

Класс Contact, поля которого мы добавляем в таблицу:

public class Contact {
private String firstName;
private String secondName;
private String number;

public Contact(){
    firstName="Введите имя";
    secondName="Введите фамилию";
    number="Введите мобильный номер";
}
public String getFirstName() {
    return firstName;
}
public void setFirstName(String firstName) {
    this.firstName = firstName;
}
public String getSecondName() {
    return secondName;
}
public void setSecondName(String secondName) {
    this.secondName = secondName;
}
public String getNumber() {
    return number;
}
public void setNumber(String number) {
    this.number = number;
}

}

При создании таблицы я передаю в конструктор список Contacts, который эта таблица должна отобразить, но метод getRowCount() выкидывает ошибку:

Exception in thread "main" java.lang.NullPointerException

Насколько я знаю эта ошибка выкидывается когда ссылка на список = null, но это не так я уже несколько раз выводил этот список в этом же объекте и всё отображалось.

Вот ошибка полностью:

Exception in thread "main" java.lang.NullPointerException at TableModel.getRowCount(TableModel.java:39) at javax.swing.table.DefaultTableModel.setDataVector(DefaultTableModel.java:224) at javax.swing.table.DefaultTableModel.(DefaultTableModel.java:124) at javax.swing.table.DefaultTableModel.(DefaultTableModel.java:106) at javax.swing.table.DefaultTableModel.(DefaultTableModel.java:86) at TableModel.(TableModel.java:9) at ContactsBook.go(ContactsBook.java:55) at ContactsBook.main(ContactsBook.java:20)

Answer 1

Когда вы вызываете конструктор для TableModel, он в свою очередь, в конструкторе, неявно вызывает конструктор DefaultTableModel.

public TableModel(ArrayList<Contact> contacts) {
    super(); //DefaultTableModel()
    this.contacts = contacts;
}

Как видно, он вызывается до того, как вы присвоили contacts. В свою очередь в конструкторе DefaultTableModel вызывает метод setDataVector.

public void setDataVector(Vector<? extends Vector> dataVector,
                          Vector<?> columnIdentifiers) {
    this.dataVector = nonNullVector((Vector<Vector>)dataVector);
    this.columnIdentifiers = nonNullVector(columnIdentifiers);
    justifyRows(0, getRowCount());
    fireTableStructureChanged();
}

Как видно, в нём вызывается переопределённый вами метод getRowCount(), который и вызывает contacts.size(), до того момента, как contacts был присвоен.

READ ALSO
Может ли стать причиной утечки памяти объявление SharedPreferences и SQLiteDatabase статическими?

Может ли стать причиной утечки памяти объявление SharedPreferences и SQLiteDatabase статическими?

Я обычно в небольших приложениях объявляю SharedPreferences статическим, и SQLiteDatabase статическим, может ли это стать причиной утечки памяти? Или мне...

145
Получить верхний пиксель у изображения

Получить верхний пиксель у изображения

Возможно ли как-то получить верхний пиксель (верхнюю границу) у изображения?

152
Читабельность и грамотность кода

Читабельность и грамотность кода

Не знаю, можно ли выкладывать такие просьбы тут, но руку мне за это не отрежут

152
Практика для изучения Java? [закрыт]

Практика для изучения Java? [закрыт]

Неоднократно был задан данный вопрос, исследуя его я сделал очевидные выводы :

186