我目前正在创建,或更多尝试为我的项目创建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的构造函数....
传递引用给UIpublic 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;
}
}
}