0

我目前正在创建或更多尝试为我的项目创建 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>();

谢谢您的帮助。

4

1 回答 1

3

从未LinkedList初始化...

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

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

更新

您可以使用任意数量的选项将 main 的引用传递LinkedList到 UI 中,但这将归结为您的工作流程的工作方式。

你可以...

通过它的构造函数传递对 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;
        }

    }

}
于 2013-04-10T07:44:47.597 回答