GUI不使用自定义AbstractTableModel。错误“未知来源”

时间:2013-04-10 07:42:41

标签: java swing linked-list jtable abstracttablemodel

我正在创建或者更多尝试为我的项目创建GUI。我现在需要做的是创建一个从LinkedList读取数据的JTable。我有一个自定义的TableAbstractModel。

public class StudentTableModel extends AbstractTableModel {

public static final String[] columnNames = { "ID", "First Name",
        "Last Name" };
private LinkedList<Student> data;

public StudentTableModel(LinkedList<Student> data) {
    this.data = data;
}

@Override
public int getColumnCount() {
    return columnNames.length;
}

@Override
public String getColumnName(int column) {
    return columnNames[column];
}

@Override
public int getRowCount() {
    return data.size();
}

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
    Student student = data.get(rowIndex);
    if (student == null) {
        return null;
    }
    switch (columnIndex) {
    case 0:
        return student.getID();
    case 1:
        return student.getFirstname();
    case 2:
        return student.getLastname();
    default:
        return null;
    }
}

}

现在我正在尝试构建一个非常基本的布局,仅包含表格,以及相应的JTextfields和JButtons来测试表格是否真正有效。

public class GUI extends JFrame {

private JTextField StudentID;
private JTextField Firstname;
private JTextField Lastname;
private JTextField Group;
private JButton Add;
private static Database DB; // << Does this have to be static? Eclipse tells me it needs to be, but I am not sure.
private JTable StudentTable;

public GUI(Database DB) {
    super("Theatre Management");
    setExtendedState(JFrame.MAXIMIZED_BOTH);
    this.DB = DB;
    LinkedList<Student> data = null;

    setLayout(new FlowLayout());
    StudentID = new JTextField("Enter Student ID", 10);
    Firstname = new JTextField("Enter First Name");
    Lastname = new JTextField("Enter Last Name");
    Group = new JTextField("Enter Group ID");
    Add = new JButton("Add Student");
    StudentTable = new JTable();
    StudentTable.setModel(new StudentTableModel(data));
    JScrollPane scrollPane = new JScrollPane(StudentTable);
    StudentTable.setFillsViewportHeight(true);

    add(StudentTable);
    add(StudentID);
    add(Firstname);
    add(Lastname);
    add(Group);
    add(Add);
    add(scrollPane);

    addStudentEvent add = new addStudentEvent();
    Add.addActionListener(add);

}

public static void createAndShow() {
    GUI Database = new GUI(DB);
    Database.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    Database.setVisible(true);

}

public static void main(String[] args) {
    GUI.createAndShow();

}

private class addStudentEvent implements ActionListener {
    public void actionPerformed(ActionEvent event) {
        int G = Integer.parseInt(Group.getText());
        int ID = Integer.parseInt(StudentID.getText());
        String First = Firstname.getText();
        String Last = Lastname.getText();

        DB.getGroup(G).addStudent(ID, First, Last);
        DB.addStudent(ID, First, Last);
    }

}

}

现在,问题是,一旦我尝试运行GUI,我就会收到一大堆错误。

Exception in thread "main" java.lang.NullPointerException
at theatremanagement.StudentTableModel.getRowCount(StudentTableModel.java:29)
at javax.swing.JTable.getRowCount(Unknown Source)
at javax.swing.plaf.basic.BasicTableUI.createTableSize(Unknown Source)
at javax.swing.plaf.basic.BasicTableUI.getPreferredSize(Unknown Source)
at javax.swing.JComponent.getPreferredSize(Unknown Source)
at java.awt.FlowLayout.layoutContainer(Unknown Source)
at java.awt.Container.layout(Unknown Source)
at java.awt.Container.doLayout(Unknown Source)
at java.awt.Container.validateTree(Unknown Source)
at java.awt.Container.validateTree(Unknown Source)
at java.awt.Container.validateTree(Unknown Source)
at java.awt.Container.validateTree(Unknown Source)
at java.awt.Container.validate(Unknown Source)
at java.awt.Container.validateUnconditionally(Unknown Source)
at java.awt.Window.show(Unknown Source)
at java.awt.Component.show(Unknown Source)
at java.awt.Component.setVisible(Unknown Source)
at java.awt.Window.setVisible(Unknown Source)
at theatremanagement.GUI.createAndShow(GUI.java:59)
at theatremanagement.GUI.main(GUI.java:64)

我现在真的被困住,并且不知道如何解决这个问题。如果有人能告诉我我做错了什么,那就太好了。另一方面,我必须在我的程序中使用LinkedList,在不同的类中。 TableModel如何知道我想要哪一个?我是否需要向TableModel添加任何内容,以便在添加或删除学生后立即自动更新表格?

更新

private JTable setStudentList(LinkedList<Student> Studentlist) {
    JTable StudentTable = new JTable();
    StudentTable.setModel(new StudentTableModel(Studentlist));
    JScrollPane scrollPane = new JScrollPane(StudentTable);
    StudentTable.setFillsViewportHeight(true);
    return StudentTable;

此方法是否可以使用链表创建表?然后我会将该方法称为

setStudentList(Studentlist); 

如果我这样初始化了一个空的LinkedList:

LinkedList<Student> StudentList = new LinkedList<Student>();

感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

LinkedList从未被宣布过......

LinkedList<Student> data = null;
// ... ///
StudentTable.setModel(new StudentTableModel(data));

这意味着当调用getRowCount时,data对象为null,因此NullPointerException

<强>更新

您可以使用任意数量的选项将对LinkedList的引用传递到用户界面,但这将取决于您的工作流程的工作方式。

你可以......

通过它的构造函数将引用传递给UI ....

public GUI(Database DB, LinkedList<Student> students) {...}

你可以......

通过您LinkedList类...

中的方法传递GUI
public class GUI extends JFrame {

    //...//

    public GUI(Database DB) {...}

    public void setStudent(LinkedList<Student> students) {
        StudentTable.setModel(new StudentTableModel(students));
    }
}

更新了示例

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.AbstractTableModel;

public class PassTable {

    public static void main(String[] args) {
        new PassTable();
    }

    public PassTable() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public class TestPane extends JPanel {

        private ExampleTable example;

        public TestPane() {
            setLayout(new BorderLayout());
            example = new ExampleTable();
            add(example);
            JButton add = new JButton("Add");
            add(add, BorderLayout.SOUTH);
            add.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    LinkedList<Person> people = new LinkedList<Person>();
                    people.add(new Person("A", "A", 1));
                    people.add(new Person("B", "B", 2));
                    people.add(new Person("C", "C", 3));
                    people.add(new Person("D", "D", 4));
                    example.setPeople(people);
                }
            });
        }

    }

    public class ExampleTable extends JPanel {

        private JTable table;

        public ExampleTable() {
            this(new LinkedList<Person>());
        }

        public ExampleTable(LinkedList<Person> people) {
            setLayout(new BorderLayout());
            table = new JTable(new SampleTableModel(people));
            add(new JScrollPane(table));
        }

        public void setPeople(LinkedList<Person> people) {
            table.setModel(new SampleTableModel(people));
        }

    }

    public class SampleTableModel extends AbstractTableModel {

        private LinkedList<Person> data;

        public SampleTableModel(LinkedList<Person> data) {
            this.data = data;
        }

        @Override
        public int getRowCount() {
            return data.size();
        }

        @Override
        public String getColumnName(int column) {
            String name = "";
            switch (column) {
                case 0:
                    name = "First name";
                    break;
                case 1:
                    name = "Last name";
                    break;
                case 2:
                    name = "Age";
                    break;
            }
            return name;
        }

        @Override
        public int getColumnCount() {
            return 3;
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            Object value = null;
            Person person = data.get(rowIndex);
            switch (columnIndex) {
                case 0:
                    value = person.getFirstName();
                    break;
                case 1:
                    value = person.getLastName();
                    break;
                case 2:
                    value = person.getAge();
                    break;
            }
            return value;
        }

    }

    public class Person {
        private String firstName;
        private String lastName;
        private int age;

        public Person(String firstName, String lastName, int age) {
            this.firstName = firstName;
            this.lastName = lastName;
            this.age = age;
        }

        public int getAge() {
            return age;
        }

        public String getFirstName() {
            return firstName;
        }

        public String getLastName() {
            return lastName;
        }

    }

}