Reputation: 99
I'm having issues creating a table model to populate a JTable with Student objects from my custom linked list. Unfortunately, I have to create my own list instead of using the standard Java linked list.
Here's my primary class
import java.util.ArrayList;
import java.util.*;
import java.io.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.table.*;
public class StudentInterface {
public static void main(String[] args){
new StudentInterface();
}
//create a linked list
MyList studentPack = new MyList();
public StudentInterface (){
//create jFrame
JFrame jFrame = new JFrame("Student Information Interface");
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setSize(400,300);
jFrame.setVisible(true);
jFrame.setDefaultLookAndFeelDecorated(true);
jFrame.setPreferredSize(new Dimension(600, 400));
//create content panes
JPanel headerPanel = new JPanel();
JPanel tablePanel = new JPanel();
JPanel buttonPanel = new JPanel();
JPanel combinedPanel = new JPanel();
headerPanel.setLayout(new BorderLayout());
tablePanel.setLayout(new FlowLayout());
buttonPanel.setLayout(new FlowLayout());
combinedPanel.setLayout(new BorderLayout());
//add label to header content panel
JLabel headerLabel1 = new JLabel("Welcome to the Student Information Interface");
JLabel headerLabel2 = new JLabel("***Click a cell to edit data***");
JLabel headerLabel3 = new JLabel("***Click a column header to sort***");
headerLabel1.setHorizontalAlignment(JLabel.CENTER);
headerLabel2.setHorizontalAlignment(JLabel.CENTER);
headerLabel3.setHorizontalAlignment(JLabel.CENTER);
headerPanel.add(headerLabel1, BorderLayout.NORTH);
headerPanel.add(headerLabel2, BorderLayout.CENTER);
headerPanel.add(headerLabel3, BorderLayout.SOUTH);
//Where the GUI is created:
JMenuBar menuBar;
JMenu menu, submenu;
JMenuItem exitMenuItem;
JMenuItem saveMenuItem;
JMenuItem loadMenuItem;
//Create the menu bar.
menuBar = new JMenuBar();
//Build the main menu.
menu = new JMenu("File");
menu.setMnemonic(KeyEvent.VK_A);
menu.getAccessibleContext().setAccessibleDescription("The only menu in this program that has menu items");
menuBar.add(menu);
//create menu items
exitMenuItem = new JMenuItem("Exit",KeyEvent.VK_T);
menu.add(exitMenuItem);
jFrame.setJMenuBar(menuBar);
//create table
tableModel model;
model = new tableModel(new MyList());
JTable table = new JTable(model);
//add list to list content panel
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setPreferredSize(new Dimension(580, 400));
tablePanel.add(scrollPane);
//add buttons to button content panel
JButton addButton = new JButton("Add");
JButton removeButton = new JButton("Remove");
buttonPanel.add(addButton);
buttonPanel.add(removeButton);
addButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//verify pack is not full
int packSize = studentPack.size();
if (packSize >= 10)
{
JOptionPane.showMessageDialog(null,
"The interface is full. Please remove a student first.",
"Interface Full",
JOptionPane.WARNING_MESSAGE);
return;
}
JPanel p1 = new JPanel(new GridLayout(2,1));
JTextField t1 = new JTextField();
JLabel labell = new JLabel("Please enter the first name of the student you would like to add:");
p1.add(labell);
p1.add(t1);
JOptionPane.showMessageDialog(null,p1,"First Name",JOptionPane.PLAIN_MESSAGE);
String userFirstName = t1.getText();
JPanel p2 = new JPanel(new GridLayout(2,1));
JTextField t2 = new JTextField();
JLabel label2 = new JLabel("Please enter the last name of the student you would like to add:");
p2.add(label2);
p2.add(t2);
JOptionPane.showMessageDialog(null,p2,"Last Name",JOptionPane.PLAIN_MESSAGE);
String userLastName = t2.getText();
JPanel p3 = new JPanel(new GridLayout(2,1));
JTextField t3 = new JTextField();
JLabel label3 = new JLabel("Please enter the major of the student you would like to add:");
p3.add(label3);
p3.add(t3);
JOptionPane.showMessageDialog(null,p3,"Major",JOptionPane.PLAIN_MESSAGE);
String userMajor = t3.getText();
JPanel p4 = new JPanel(new GridLayout(2,1));
JTextField t4 = new JTextField();
JLabel label4 = new JLabel("Please enter the NetID of the student you would like to add:");
p4.add(label4);
p4.add(t4);
JOptionPane.showMessageDialog(null,p4,"NetID",JOptionPane.PLAIN_MESSAGE);
String userNetID = t4.getText();
JPanel p5 = new JPanel(new GridLayout(2,1));
JTextField t5 = new JTextField();
JLabel label5 = new JLabel("Please enter the gender of the student you would like to add:");
p5.add(label5);
p5.add(t5);
JOptionPane.showMessageDialog(null,p5,"Gender",JOptionPane.PLAIN_MESSAGE);
String userGender = t5.getText();
JPanel p6 = new JPanel(new GridLayout(2,1));
JTextField t6 = new JTextField();
JLabel label6 = new JLabel("Please enter the UIN of the student you would like to add:");
p6.add(label6);
p6.add(t6);
JOptionPane.showMessageDialog(null,p6,"UIN",JOptionPane.PLAIN_MESSAGE);
String userUIN = t6.getText();
JPanel p7 = new JPanel(new GridLayout(2,1));
JTextField t7 = new JTextField();
JLabel label7 = new JLabel("Please enter the age of the student you would like to add:");
p7.add(label7);
p7.add(t7);
JOptionPane.showMessageDialog(null,p7,"Age",JOptionPane.PLAIN_MESSAGE);
String userAgeInput = t7.getText();
int userAge = Integer.parseInt(userAgeInput);
JPanel p8 = new JPanel(new GridLayout(2,1));
JTextField t8 = new JTextField();
JLabel label8 = new JLabel("Please enter the GPA of the student you would like to add:");
p8.add(label8);
p8.add(t8);
JOptionPane.showMessageDialog(null,p8,"GPA",JOptionPane.PLAIN_MESSAGE);
String userGPAInput = t8.getText();
double userGPA = Double.parseDouble(userGPAInput);
//create student Student
Student studentStudent = new Student(userFirstName, userLastName, userMajor, userGPA, userUIN, userNetID, userAge, userGender);
//store Student in linked list
model.addStudent(studentStudent);
}
});
removeButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//verify pack is not full
if (studentPack.size() == 0)
{
JOptionPane.showMessageDialog(null,
"The interface is empty. Please add a student first.",
"Interface Empty",
JOptionPane.WARNING_MESSAGE);
return;
}
JPanel p9 = new JPanel(new GridLayout(2,1));
JTextField t9 = new JTextField();
JLabel label9 = new JLabel("Please enter the first name of the student you would like to remove: **Case Sensitive**");
p9.add(label9);
p9.add(t9);
JOptionPane.showMessageDialog(null,p9,"First Name",JOptionPane.PLAIN_MESSAGE);
String userFirstName = t9.getText();
JPanel p10 = new JPanel(new GridLayout(2,1));
JTextField t10 = new JTextField();
JLabel label10 = new JLabel("Please enter the last name of the student you would like to remove: **Case Sensitive**");
p10.add(label10);
p10.add(t10);
JOptionPane.showMessageDialog(null,p10,"First Name",JOptionPane.PLAIN_MESSAGE);
String userLastName = t10.getText();
//remove student Student in linked list
/*for (Student student : studentPack)
{
if ((student.getFirstName().equals(userFirstName)) && (student.getLastName().equals(userLastName)))
{
studentPack.remove(student);
break;
}
}
model.removeStudent(int i);
*/}
});
exitMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
//nest button and list panels in combined content panel
combinedPanel.add(headerPanel, BorderLayout.NORTH);
combinedPanel.add(tablePanel, BorderLayout.CENTER);
combinedPanel.add(buttonPanel, BorderLayout.SOUTH);
//add combined content panel to frame
jFrame.add(combinedPanel);
jFrame.pack();
jFrame.setLocationRelativeTo(null);
JOptionPane.showMessageDialog(null,
"***Click a cell to edit data*** \n ***Click a column header to sort***", "How to edit/sort data", JOptionPane.INFORMATION_MESSAGE);
}
public class tableModel extends AbstractTableModel {
public final String[] columnNames = { "First Name", "Last Name", "Major:", "GPA", "UIN", "NetID", "Age", "Gender" };
private MyList data;
public tableModel(MyList 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();
}
public void addStudent(Student student) {
int row = data.size();
data.add(student);
fireTableRowsInserted(row, row);
}
public void removeStudent(int i) {
int row = data.size();
data.remove(i);
fireTableRowsDeleted(row, row);
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Student student = data.get(rowIndex);
if (student == null) {
return null;
}
switch (columnIndex) {
case 0:
return student.getFirstName();
case 1:
return student.getLastName();
case 2:
return student.getMajor();
case 3:
return student.getGPA();
case 4:
return student.getUIN();
case 5:
return student.getNetID();
case 6:
return student.getAge();
case 7:
return student.getGender();
default:
return null;
}
}
}
}
Here's the class for my student object
public class Student {
// Declare attributes here
String firstName;
String lastName;
String major;
double gpa;
String uin;
String netid;
int age;
String gender;
public Student(String newFirstName, String newLastName, String newMajor, double newGPA, String newUIN, String newNetID, int newAge, String newGender){
setFirstName(newFirstName);
setLastName(newLastName);
setMajor(newMajor);
setGPA(newGPA);
setUIN(newUIN);
setNetID(newNetID);
setAge(newAge);
setGender(newGender);
}
//Mutators
public void setFirstName(String newFirstName) {
firstName = newFirstName;
}
public void setLastName(String newLastName) {
lastName = newLastName;
}
public void setMajor(String newMajor) {
major = newMajor;
}
public void setGPA(double newGPA) {
gpa = newGPA;
}
public void setUIN(String newUIN) {
uin = newUIN;
}
public void setNetID(String newNetID) {
netid = newNetID;
}
public void setAge(int newAge) {
age = newAge;
}
public void setGender(String newGender) {
gender = newGender;
}
//Accessors
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getMajor() {
return major;
}
public double getGPA() {
return gpa;
}
public String getUIN() {
return uin;
}
public String getNetID() {
return netid;
}
public int getAge() {
return age;
}
public String getGender() {
return gender;
}
}
Here's the class for my custom list
class MyList {
private static int counter;
private Node head;
// Default constructor
public MyList() {
}
// appends the specified element to the end of this list.
public void add(Student data) {
// Initialize Node only incase of 1st element
if (head == null) {
head = new Node(data);
}
Node temp = new Node(data);
Node current = head;
// Check for NPE before iterate over current
if (current != null) {
// starting at the head node, crawl to the end of the list and then add element after last node
while (current.getNext() != null) {
current = current.getNext();
}
// the last node's "next" reference set to our new node
current.setNext(temp);
}
// increment the number of elements variable
incrementCounter();
}
private static int getCounter() {
return counter;
}
private static void incrementCounter() {
counter++;
}
private void decrementCounter() {
counter--;
}
// inserts the specified element at the specified position in this list
public void add(Student data, int index) {
Node temp = new Node(data);
Node current = head;
// Check for NPE before iterate over current
if (current != null) {
// crawl to the requested index or the last element in the list, whichever comes first
for (int i = 0; i < index && current.getNext() != null; i++) {
current = current.getNext();
}
}
// set the new node's next-node reference to this node's next-node reference
temp.setNext(current.getNext());
// now set this node's next-node reference to the new node
current.setNext(temp);
// increment the number of elements variable
incrementCounter();
}
public Student get(int index)
// returns the element at the specified position in the list.
{
// index must be 1 or higher
if (index <= 0)
return null;
Node current = null;
if (head != null) {
current = head.getNext();
for (int i = 0; i < index; i++) {
if (current.getNext() == null)
return null;
current = current.getNext();
}
return current.getData();
}
return current.getData();
}
// removes the element at the specified position in this list.
public boolean remove(int index) {
// if the index is out of range, exit
if (index < 1 || index > size())
return false;
Node current = head;
if (head != null) {
for (int i = 0; i < index; i++) {
if (current.getNext() == null)
return false;
current = current.getNext();
}
current.setNext(current.getNext().getNext());
// decrement the number of elements variable
decrementCounter();
return true;
}
return false;
}
// returns the number of elements in this list.
public int size() {
return getCounter();
}
public String toString() {
String output = "";
if (head != null) {
Node current = head.getNext();
while (current != null) {
output += "[" + current.getData().toString() + "]";
current = current.getNext();
}
}
return output;
}
private class Node {
// reference to the next node in the chain
Node next;
// data carried by the node
Student data;
// Node constructor
public Node(Student dataValue) {
next = null;
data = dataValue;
}
// another Node constructor to specify the node to point to.
@SuppressWarnings("unused")
public Node(Student dataValue, Node nextValue) {
next = nextValue;
data = dataValue;
}
public Student getData() {
return data;
}
@SuppressWarnings("unused")
public void setData(Student dataValue) {
data = dataValue;
}
public Node getNext() {
return next;
}
public void setNext(Node nextValue) {
next = nextValue;
}
}
}
Upvotes: 0
Views: 1438
Reputation: 347294
So, basically, you need to add a add
method to your StudentTableModel
which can add the new Student
to the MyList
and generate the required update events to tell the table to repaint itself.
Something like...
public void addStudent(Student student) {
int row = data.size();
data.add(student);
fireTableRowsInserted(row, row);
}
Which would be be added to your StudentTableModel
, something like...
public class StudentTableModel extends AbstractTableModel {
public final String[] columnNames = {"First Name", "Last Name", "Major:", "GPA", "UIN", "NetID", "Age", "Gender"};
private MyList data;
public StudentTableModel(MyList 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();
}
public void addStudent(Student student) {
int row = data.size();
System.out.println(row);
System.out.println(student);
data.add(student);
fireTableRowsInserted(row, row);
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Student student = data.get(rowIndex);
if (student == null) {
return null;
}
switch (columnIndex) {
case 0:
return student.getFirstName();
case 1:
return student.getLastName();
case 2:
return student.getMajor();
case 3:
return student.getGPA();
case 4:
return student.getUIN();
case 5:
return student.getNetID();
case 6:
return student.getAge();
case 7:
return student.getGender();
default:
return null;
}
}
}
Then you would actually need to apply the model to the JTable
...
private StudentTableModel model;
//...
model = new StudentTableModel(new MyList());
JTable table = new JTable(model);
and then, instead of...
Student studentStudent = new Student(userFirstName, userLastName, userMajor, userGPA, userUIN, userNetID, userAge, userGender);
//store Student in linked list
studentPack.add(studentStudent);
you would do something like...
Student studentStudent = new Student(userFirstName, userLastName, userMajor, userGPA, userUIN, userNetID, userAge, userGender);
//store Student in linked list
model.add(studentStudent);
After spending some time playing around with your code, it became evident that your MyList
has issues. My recommendation would be to test and debug your MyList
first before getting the UI involved, it will be easier
I would also take a look at How to Use Tables for more details
Upvotes: 2