From 134d2ede644810ce3849a9fa2990e9eac2509306 Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Tue, 23 Oct 2018 10:55:55 +0200 Subject: [PATCH] Display both students and student teams. --- src/main/java/nl/andrewlalis/Main.java | 3 +- .../nl/andrewlalis/model/StudentTeam.java | 5 + src/main/java/nl/andrewlalis/model/Team.java | 34 ++++- .../andrewlalis/model/database/DbHelper.java | 16 +- .../andrewlalis/ui/view/ManagementView.java | 54 +++++-- .../table_models/StudentTeamTableModel.java | 142 ++++++++++++++++++ 6 files changed, 238 insertions(+), 16 deletions(-) create mode 100644 src/main/java/nl/andrewlalis/ui/view/table_models/StudentTeamTableModel.java diff --git a/src/main/java/nl/andrewlalis/Main.java b/src/main/java/nl/andrewlalis/Main.java index af2f226..a3d727f 100644 --- a/src/main/java/nl/andrewlalis/Main.java +++ b/src/main/java/nl/andrewlalis/Main.java @@ -59,8 +59,7 @@ public class Main { private static void initializeTestingData() { try { - List teams = TeamGenerator.generateFromCSV("/home/andrew/Documents/School/ta/GithubInitializer/sampleAOOP.csv", 2); - System.out.println(teams); + List teams = TeamGenerator.generateFromCSV("/home/andrew/Documents/School/ta/GithubInitializer/student-groups.csv", 2); DbHelper.saveStudentTeams(teams); managementView.updateModels(); } catch (IOException e) { diff --git a/src/main/java/nl/andrewlalis/model/StudentTeam.java b/src/main/java/nl/andrewlalis/model/StudentTeam.java index e862411..232cd0b 100644 --- a/src/main/java/nl/andrewlalis/model/StudentTeam.java +++ b/src/main/java/nl/andrewlalis/model/StudentTeam.java @@ -112,4 +112,9 @@ public class StudentTeam extends Team { public void setTaTeam(TATeam team) { this.taTeam = team; } + + @Override + public String getDetailName() { + return this.generateRepoDescription(); + } } diff --git a/src/main/java/nl/andrewlalis/model/Team.java b/src/main/java/nl/andrewlalis/model/Team.java index eee12cb..0f153f8 100644 --- a/src/main/java/nl/andrewlalis/model/Team.java +++ b/src/main/java/nl/andrewlalis/model/Team.java @@ -1,6 +1,8 @@ package nl.andrewlalis.model; import nl.andrewlalis.model.database.BaseEntity; +import nl.andrewlalis.ui.view.components.Detailable; +import nl.andrewlalis.util.Pair; import javax.persistence.*; import java.util.ArrayList; @@ -13,7 +15,7 @@ import java.util.List; */ @Entity(name = "Team") @Table(name = "teams") -public abstract class Team extends BaseEntity { +public abstract class Team extends BaseEntity implements Detailable { /** * An identification number unique to this team alone. @@ -24,7 +26,7 @@ public abstract class Team extends BaseEntity { /** * A list of members of this team. */ - @OneToMany + @OneToMany(fetch = FetchType.EAGER) @JoinTable( name = "team_members", joinColumns = {@JoinColumn(name = "team_id")}, @@ -41,6 +43,13 @@ public abstract class Team extends BaseEntity { this.members = new ArrayList<>(); } + /** + * Constructs an empty team with a default id of -1. + */ + protected Team() { + this(-1); + } + /** * @param newId The new number number to assign to this team. */ @@ -162,4 +171,25 @@ public abstract class Team extends BaseEntity { return sb.toString(); } + @Override + public String getDetailName() { + return String.valueOf(this.getNumber()); + } + + @Override + public String getDetailDescription() { + return null; + } + + @Override + public List> getDetailPairs() { + List> pairs = new ArrayList<>(); + pairs.add(new Pair<>("Number", this.getDetailName())); + + for (int i = 0; i < this.memberCount(); i++) { + pairs.add(new Pair<>("Member " + (i + 1), this.members.get(i).getDetailName())); + } + + return pairs; + } } diff --git a/src/main/java/nl/andrewlalis/model/database/DbHelper.java b/src/main/java/nl/andrewlalis/model/database/DbHelper.java index e9e163a..f8f007c 100644 --- a/src/main/java/nl/andrewlalis/model/database/DbHelper.java +++ b/src/main/java/nl/andrewlalis/model/database/DbHelper.java @@ -3,7 +3,6 @@ package nl.andrewlalis.model.database; import nl.andrewlalis.model.Student; import nl.andrewlalis.model.StudentTeam; import org.hibernate.Session; -import org.hibernate.SessionFactory; import org.hibernate.Transaction; import java.util.List; @@ -11,6 +10,7 @@ import java.util.List; /** * This class will contain some static methods to help in the retrieval of commonly used information. */ +@SuppressWarnings("unchecked") public class DbHelper { /** @@ -18,8 +18,7 @@ public class DbHelper { * @return A list of students. */ public static List getStudents() { - SessionFactory sessionFactory = DbUtil.getSessionFactory(); - Session session = sessionFactory.openSession(); + Session session = DbUtil.getSessionFactory().openSession(); List students = (List) session.createQuery("from Student").list(); session.close(); return students; @@ -43,4 +42,15 @@ public class DbHelper { session.close(); } + /** + * Gets a list of student teams in the database. + * @return A list of student teams. + */ + public static List getStudentTeams() { + Session session = DbUtil.getSessionFactory().openSession(); + List studentTeams = (List) session.createQuery("from StudentTeam").list(); + session.close(); + return studentTeams; + } + } diff --git a/src/main/java/nl/andrewlalis/ui/view/ManagementView.java b/src/main/java/nl/andrewlalis/ui/view/ManagementView.java index f76005f..669a65f 100644 --- a/src/main/java/nl/andrewlalis/ui/view/ManagementView.java +++ b/src/main/java/nl/andrewlalis/ui/view/ManagementView.java @@ -5,6 +5,7 @@ import nl.andrewlalis.model.database.DbHelper; import nl.andrewlalis.model.database.DbUtil; import nl.andrewlalis.ui.view.components.DetailPanel; import nl.andrewlalis.ui.view.table_models.StudentTableModel; +import nl.andrewlalis.ui.view.table_models.StudentTeamTableModel; import javax.swing.*; import java.awt.*; @@ -21,6 +22,11 @@ public class ManagementView extends AbstractView { */ private StudentTableModel studentsModel; + /** + * The model for the student teams table. + */ + private StudentTeamTableModel studentTeamModel; + /** * A panel which displays the details of selected entities. */ @@ -89,7 +95,7 @@ public class ManagementView extends AbstractView { JPanel overviewPanel = new JPanel(new BorderLayout()); overviewPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - overviewPanel.add(new JLabel("Overview", SwingConstants.CENTER), BorderLayout.NORTH); + overviewPanel.add(this.buildSearchPanel(), BorderLayout.NORTH); // The real container for all the data views. JTabbedPane tabbedPane = new JTabbedPane(); @@ -103,6 +109,30 @@ public class ManagementView extends AbstractView { return overviewPanel; } + /** + * Builds a JPanel containing utilities to search the data in the various tables in the application. + * @return A JPanel containing search functionality. + */ + private JPanel buildSearchPanel() { + JPanel searchPanel = new JPanel(new BorderLayout()); + + searchPanel.add(new JLabel("Search", SwingConstants.LEFT), BorderLayout.WEST); + searchPanel.add(new JTextField(), BorderLayout.CENTER); + + return searchPanel; + } + + /** + * Provides a JScrollPane and JPanel to surround a table. + * @param table The table to wrap. + * @return The JPanel containing the table, wrapped in a JScrollPane. + */ + private JPanel buildGenericTablePanel(JTable table) { + JPanel surroundingPanel = new JPanel(new BorderLayout()); + surroundingPanel.add(new JScrollPane(table), BorderLayout.CENTER); + return surroundingPanel; + } + /** * @return A JPanel to be put into a tab for display of a list of students. */ @@ -110,21 +140,27 @@ public class ManagementView extends AbstractView { // Initialize the model, table, and a surrounding scroll pane. this.studentsModel = new StudentTableModel(DbHelper.getStudents()); - JPanel surroundingPanel = new JPanel(new BorderLayout()); - JTable table = new JTable(this.studentsModel); table.setFillsViewportHeight(true); table.getSelectionModel().addListSelectionListener(listSelectionEvent -> { detailPanel.setDetailableEntity(studentsModel.getStudentAt(table.getSelectedRow())); }); - JScrollPane scrollPane = new JScrollPane(table); - - surroundingPanel.add(scrollPane, BorderLayout.CENTER); - return surroundingPanel; + return this.buildGenericTablePanel(table); } + /** + * @return A JPanel to be put into a tab for display of a list of student teams. + */ private JPanel buildStudentTeamsTablePanel() { - return new JPanel(); + this.studentTeamModel = new StudentTeamTableModel(DbHelper.getStudentTeams()); + + JTable table = new JTable(this.studentTeamModel); + table.setFillsViewportHeight(true); + table.getSelectionModel().addListSelectionListener(listSelectionEvent -> { + detailPanel.setDetailableEntity(studentTeamModel.getStudentTeamAt(table.getSelectedRow())); + }); + + return this.buildGenericTablePanel(table); } private JPanel buildTAsTablePanel() { @@ -136,6 +172,6 @@ public class ManagementView extends AbstractView { */ public void updateModels() { this.studentsModel.setStudentsList(DbHelper.getStudents()); - + this.studentTeamModel.setStudentTeamsList(DbHelper.getStudentTeams()); } } diff --git a/src/main/java/nl/andrewlalis/ui/view/table_models/StudentTeamTableModel.java b/src/main/java/nl/andrewlalis/ui/view/table_models/StudentTeamTableModel.java new file mode 100644 index 0000000..c88ae14 --- /dev/null +++ b/src/main/java/nl/andrewlalis/ui/view/table_models/StudentTeamTableModel.java @@ -0,0 +1,142 @@ +package nl.andrewlalis.ui.view.table_models; + +import nl.andrewlalis.model.Student; +import nl.andrewlalis.model.StudentTeam; + +import javax.swing.table.AbstractTableModel; +import java.util.ArrayList; +import java.util.List; + +/** + * This table model represents the list of student teams. + */ +public class StudentTeamTableModel extends AbstractTableModel { + + /** + * The container for the data objects. + */ + private List studentTeamsList; + + /** + * The column headers for this model. In addition to these headers, this model will dynamically create headers for + * each additional student to be listed in the table. + */ + private final String[] staticColumns = {"Number", "Member Count"}; + + /** + * Dynamic columns which are generated depending on the teams. + */ + private String[] columns = {}; + + public StudentTeamTableModel() { + this.studentTeamsList = new ArrayList<>(); + } + + public StudentTeamTableModel(List teams) { + super(); + this.setStudentTeamsList(teams); + } + + /** + * Sets a new list of student teams as the data for this list model. + * @param newList A list of student teams to display in the table model. + */ + public void setStudentTeamsList(List newList) { + this.studentTeamsList = newList; + int maxMembers = this.getMaxMemberCount(); + if (this.columns.length != maxMembers) { + this.generateColumnNames(maxMembers); + this.fireTableStructureChanged(); + } + this.fireTableDataChanged(); + } + + /** + * Gets the student team in a particular row. + * @param row The row of the table. + * @return The student team object at the specified row, or null if none is found. + */ + public StudentTeam getStudentTeamAt(int row) { + if (row >= 0 && row < this.studentTeamsList.size()) { + return this.studentTeamsList.get(row); + } + return null; + } + + @Override + public int getRowCount() { + return this.studentTeamsList.size(); + } + + @Override + public int getColumnCount() { + return this.columns.length; + } + + @Override + public String getColumnName(int i) { + if (i >= 0 && i < this.columns.length) { + return this.columns[i]; + } else { + return null; + } + } + + @Override + public Object getValueAt(int i, int i1) { + StudentTeam team = this.getStudentTeamAt(i); + + switch (i1) { + case 0: + return team.getId(); + case 1: + return team.memberCount(); + default: + return this.getMemberInColumn(team, i1); + } + } + + /** + * Gets a particular student name in a column of the table. This is used for the staticColumns which show all members in + * the team. + * @param team The team for which to search for a student in. + * @param column The table column. + * @return The student detail name in a particular column, or null if none exists. + */ + private String getMemberInColumn(StudentTeam team, int column) { + Student[] students = team.getStudents(); + int index = column - this.staticColumns.length; // Subtract the number of static staticColumns. + if (index >= 0 && index < students.length) { + return students[index].getDetailName(); + } else { + return null; + } + } + + /** + * Gets the highest member count in the list of student teams. + * @return The maximum member count of all teams. + */ + private int getMaxMemberCount() { + int max = 0; + for (StudentTeam team : this.studentTeamsList) { + if (team.memberCount() > max) { + max = team.memberCount(); + } + } + return max; + } + + /** + * Generates column names, including some procedurally generated headers based on the number of members in the team. + * @param maxMembers The highest number of members a team has. + */ + private void generateColumnNames(int maxMembers) { + this.columns = new String[this.staticColumns.length + maxMembers]; + this.columns[0] = this.staticColumns[0]; + this.columns[1] = this.staticColumns[1]; + for (int i = 0; i < maxMembers; i++) { + this.columns[i + 2] = "Member " + (i + 1); + } + } +}