Сама таблица:
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)
Когда вы вызываете конструктор для 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
был присвоен.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Я обычно в небольших приложениях объявляю SharedPreferences статическим, и SQLiteDatabase статическим, может ли это стать причиной утечки памяти? Или мне...
Возможно ли как-то получить верхний пиксель (верхнюю границу) у изображения?
Не знаю, можно ли выкладывать такие просьбы тут, но руку мне за это не отрежут
Неоднократно был задан данный вопрос, исследуя его я сделал очевидные выводы :