java - GUI 不适用于自定义 AbstractTableModel。错误 "Unknown Source"

标签 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>();

感谢您的帮助。

最佳答案

LinkedList 永远不会初始化...

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

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

已更新

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

你可以...

通过 UI 的构造函数传递对 UI 的引用...

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

你可以...

通过 GUI 类中的方法传递 LinkedList...

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

    }

}

关于java - GUI 不适用于自定义 AbstractTableModel。错误 "Unknown Source",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15919840/

相关文章:

java - 如何创建多个相关的 JCombobox?

java - 在java中使用多个数据库连接的有效方法

java - 区分 JComboBox 中的选定项目

java - Swing 自定义组件

java - GridBagLayout - 图表和标签的放置

c - 链表段错误

c++ - 在单链表的末尾移动元音

c++ - 试图指向链表中的前一个节点

javac编译并执行2个java文件

java - 从命令行调用 OSGi 服务