Improvements and new version in development #5

Merged
andrewlalis merged 13 commits from improvements_1 into master 2018-10-23 12:23:29 +00:00
12 changed files with 351 additions and 4 deletions
Showing only changes of commit e57897a005 - Show all commits

View File

@ -4,6 +4,7 @@ import nl.andrewlalis.command.CommandExecutor;
import nl.andrewlalis.command.executables.*;
import nl.andrewlalis.git_api.GithubManager;
import nl.andrewlalis.ui.view.InitializerApp;
import nl.andrewlalis.ui.view.ManagementView;
import nl.andrewlalis.ui.view.StartView;
import nl.andrewlalis.util.CommandLine;
import nl.andrewlalis.util.Logging;
@ -18,6 +19,11 @@ public class Main {
private static final Logger logger = Logger.getGlobal();
/**
* The main application's view, which should be able to be referenced in many places.
*/
private static ManagementView managementView;
public static void main(String[] args) {
// Parsed command line arguments.
@ -50,7 +56,7 @@ public class Main {
"Program initialized.");
GithubManager manager = new GithubManager();
StartView startView = new StartView(manager, "InitializerTesting", userOptions.get("token"));
managementView = new ManagementView(manager);
// SessionFactory factory = DbUtil.getSessionFactory();
// Session session = factory.openSession();
@ -58,6 +64,15 @@ public class Main {
// System.out.println(session.save(new Student(1, "a", "a@e.com", "git", null)));
// session.getTransaction().commit();
// session.close();
StartView startView = new StartView(manager, "InitializerTesting", userOptions.get("token"));
}
/**
* @return The management view used for the application.
*/
public static ManagementView getManagementView() {
return managementView;
}
}

View File

@ -28,6 +28,13 @@ public class Student extends Person {
)
private List<Student> preferredPartners;
/**
* The team that this student is assigned to.
*/
@ManyToOne
@JoinColumn(name = "team_id")
private StudentTeam team;
/**
* Constructs an empty student object.
*/
@ -73,4 +80,19 @@ public class Student extends Person {
t.addMember(this);
return t;
}
/**
* Assigns this student to the given team, from the student's perspective.
* @param team The team to set as the assigned team.
*/
public void assignToTeam(StudentTeam team) {
this.team = team;
}
/**
* @return The team that this student is assigned to. May return null if the student is unassigned.
*/
public StudentTeam getAssignedTeam() {
return this.team;
}
}

View File

@ -0,0 +1,26 @@
package nl.andrewlalis.model.database;
import nl.andrewlalis.model.Student;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import java.util.List;
/**
* This class will contain some static methods to help in the retrieval of commonly used information.
*/
public class DbHelper {
/**
* Gets a list of students in the database.
* @return A list of students.
*/
public static List<Student> getStudents() {
SessionFactory sessionFactory = DbUtil.getSessionFactory();
Session session = sessionFactory.openSession();
List<Student> students = (List<Student>) session.createQuery("from Student").list();
session.close();
return students;
}
}

View File

@ -0,0 +1,15 @@
package nl.andrewlalis.ui.control.listeners.input_students_file_view;
import nl.andrewlalis.ui.control.listeners.ViewChangeListener;
import nl.andrewlalis.ui.view.AbstractView;
/**
* Listens for when the user clicks 'Done' after selecting a file to input.
*/
public class DoneListener extends ViewChangeListener {
public DoneListener(AbstractView previousView, AbstractView newView) {
super(previousView, newView);
}
}

View File

@ -1,8 +1,13 @@
package nl.andrewlalis.ui.control.listeners.input_students_file_view;
import nl.andrewlalis.Main;
import nl.andrewlalis.model.Student;
import nl.andrewlalis.model.StudentTeam;
import nl.andrewlalis.model.database.DbUtil;
import nl.andrewlalis.ui.view.InputStudentsFileView;
import nl.andrewlalis.util.TeamGenerator;
import org.hibernate.Session;
import org.hibernate.Transaction;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
@ -54,7 +59,20 @@ public class FileSelectListener implements ActionListener {
int teamSize = this.fileView.getStudentsPerTeam();
try {
List<StudentTeam> teams = TeamGenerator.generateFromCSV(chooser.getSelectedFile().getAbsolutePath(), teamSize);
System.out.println(teams);
Session session = DbUtil.getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
for (StudentTeam team : teams) {
for (Student s : team.getStudents()) {
session.save(s);
}
session.save(team);
}
tx.commit();
session.close();
Main.getManagementView().updateModels();
} catch (IOException e) {
e.printStackTrace();
}

View File

@ -23,6 +23,11 @@ public abstract class AbstractView extends JFrame {
*/
private List<AbstractView> childViews;
/**
* A list of views which lead to this one.
*/
private List<AbstractView> parentViews;
/**
* Initializes the view by packing the content pane as it is defined by any child, and setting some generic swing
* values.
@ -30,11 +35,13 @@ public abstract class AbstractView extends JFrame {
* @param startVisible Whether or not to start the view as visible.
* @param defaultCloseOperation What to do when the user closes the window.
* @param preferredSize The preferred size of the view.
* @param githubManager The manager used for this view.
*/
AbstractView(String title, boolean startVisible, int defaultCloseOperation, Dimension preferredSize, GithubManager githubManager) {
super(title);
this.githubManager = githubManager;
this.childViews = new ArrayList<>();
this.parentViews = new ArrayList<>();
this.setContentPane(this.buildContentPane());
this.setDefaultCloseOperation(defaultCloseOperation);
if (preferredSize != null) {
@ -95,4 +102,33 @@ public abstract class AbstractView extends JFrame {
protected final void addChildView(AbstractView view) {
this.childViews.add(view);
}
/**
* @return The list of children of this view.
*/
protected final List<AbstractView> getChildViews() {
return this.childViews;
}
/**
* Adds a view as linked to this one as a parent.
* @param view The parent view.
*/
protected final void addParentView(AbstractView view) {
this.parentViews.add(view);
}
/**
* @return The list of parents of this view.
*/
protected final List<AbstractView> getParentViews() {
return this.parentViews;
}
/**
* Removes all parents registered to this view.
*/
protected final void removeParents() {
this.parentViews.clear();
}
}

View File

@ -44,6 +44,7 @@ public class CreateAssignmentsView extends AbstractView {
JButton nextButton = new JButton("Next");
InputStudentsFileView inputStudentsFileView = new InputStudentsFileView(this.getGithubManager());
this.addChildView(inputStudentsFileView);
inputStudentsFileView.addParentView(this);
nextButton.addActionListener(new NextListener(this, inputStudentsFileView));
contentPane.add(nextButton, BorderLayout.SOUTH);

View File

@ -1,6 +1,8 @@
package nl.andrewlalis.ui.view;
import nl.andrewlalis.Main;
import nl.andrewlalis.git_api.GithubManager;
import nl.andrewlalis.ui.control.listeners.input_students_file_view.DoneListener;
import nl.andrewlalis.ui.control.listeners.input_students_file_view.FileSelectListener;
import javax.swing.*;
@ -34,7 +36,7 @@ public class InputStudentsFileView extends AbstractView {
JPanel inputPanel = new JPanel();
inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.PAGE_AXIS));
// Button to select a file.
JButton selectFileButton = new JButton("Select File");
this.studentsPerTeamField = new JTextField("2");
inputPanel.add(this.generateTextFieldPanel("How many students per team?", this.studentsPerTeamField));
@ -43,7 +45,10 @@ public class InputStudentsFileView extends AbstractView {
contentPane.add(inputPanel, BorderLayout.CENTER);
// Button to confirm and move to the next view.
JButton doneButton = new JButton("Done");
Main.getManagementView().addParentView(this);
doneButton.addActionListener(new DoneListener(this, Main.getManagementView()));
contentPane.add(doneButton, BorderLayout.SOUTH);
return contentPane;

View File

@ -0,0 +1,114 @@
package nl.andrewlalis.ui.view;
import nl.andrewlalis.git_api.GithubManager;
import nl.andrewlalis.model.database.DbHelper;
import nl.andrewlalis.model.database.DbUtil;
import nl.andrewlalis.ui.view.table_models.StudentTableModel;
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
* The view in which the user manages a course.
*/
public class ManagementView extends AbstractView {
/**
* The model for the students table.
*/
private StudentTableModel studentsModel;
public ManagementView(GithubManager githubManager) {
super(
"Course Management",
false,
DISPOSE_ON_CLOSE,
null,
githubManager
);
this.setExtendedState(this.getExtendedState() | JFrame.MAXIMIZED_BOTH);
// Dispose of all parents when this window closes.
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent windowEvent) {
for (AbstractView parent : getParentViews()) {
parent.dispose();
}
DbUtil.tearDown();
}
});
}
@Override
protected JPanel buildContentPane() {
JPanel contentPane = new JPanel(new BorderLayout());
contentPane.add(this.buildCommandPanel(), BorderLayout.WEST);
contentPane.add(this.buildDetailPanel(), BorderLayout.EAST);
contentPane.add(this.buildOverviewPanel(), BorderLayout.CENTER);
return contentPane;
}
/**
* @return A JPanel for the command prompt interface.
*/
private JPanel buildCommandPanel() {
JPanel commandPanel = new JPanel(new BorderLayout());
commandPanel.add(new JLabel("Commands", SwingConstants.CENTER), BorderLayout.NORTH);
commandPanel.add(new JTextArea("Command prompt area goes here."), BorderLayout.CENTER);
// Construct the sub-panel for commands at the bottom of the panel.
JPanel inputPanel = new JPanel(new BorderLayout());
JTextField commandTextField = new JTextField();
inputPanel.add(commandTextField, BorderLayout.CENTER);
commandPanel.add(inputPanel, BorderLayout.SOUTH);
return commandPanel;
}
/**
* @return A JPanel for the entity details section.
*/
private JPanel buildDetailPanel() {
JPanel detailPanel = new JPanel(new BorderLayout());
detailPanel.add(new JLabel("Details", SwingConstants.CENTER), BorderLayout.NORTH);
return detailPanel;
}
/**
* @return Builds the overview panel, containing a listing of entities.
*/
private JPanel buildOverviewPanel() {
JPanel overviewPanel = new JPanel(new BorderLayout());
overviewPanel.add(new JLabel("Overview"), BorderLayout.NORTH);
// The real container for all the data views.
JTabbedPane tabbedPane = new JTabbedPane();
this.studentsModel = new StudentTableModel(DbHelper.getStudents());
JTable studentsTable = new JTable(this.studentsModel);
JScrollPane studentsScrollPane = new JScrollPane(studentsTable);
tabbedPane.addTab("Students", studentsScrollPane);
overviewPanel.add(tabbedPane, BorderLayout.CENTER);
return overviewPanel;
}
/**
* Updates all models in the management view in accordance with the database.
*/
public void updateModels() {
this.studentsModel.setStudentsList(DbHelper.getStudents());
}
}

View File

@ -1,6 +1,8 @@
package nl.andrewlalis.ui.view;
import nl.andrewlalis.Main;
import nl.andrewlalis.git_api.GithubManager;
import nl.andrewlalis.ui.control.listeners.ViewChangeListener;
import nl.andrewlalis.ui.control.listeners.start_view.CreateAssignmentsRepoListener;
import javax.swing.*;
@ -61,11 +63,18 @@ public class StartView extends AbstractView {
infoInputPanel.add(this.generateTextFieldPanel("Access token:", this.accessTokenField));
JPanel buttonsPanel = new JPanel();
// Create the button for going to the Create assignments repository view.
JButton assignmentsViewButton = new JButton("Start New Course");
CreateAssignmentsView assignmentsView = new CreateAssignmentsView(this.getGithubManager());
this.addChildView(assignmentsView);
assignmentsView.addParentView(this);
assignmentsViewButton.addActionListener(new CreateAssignmentsRepoListener(this, assignmentsView));
// Create the button for going straight to the management view.
JButton managementViewButton = new JButton("Manage Existing Course");
this.addChildView(Main.getManagementView());
Main.getManagementView().addParentView(this);
managementViewButton.addActionListener(new ViewChangeListener(this, Main.getManagementView()));
buttonsPanel.add(assignmentsViewButton);
buttonsPanel.add(managementViewButton);

View File

@ -0,0 +1,74 @@
package nl.andrewlalis.ui.view.table_models;
import nl.andrewlalis.model.Student;
import javax.swing.table.AbstractTableModel;
import java.util.List;
/**
* This table model is used for the representation of a list of persons, with their basic information.
*/
public class StudentTableModel extends AbstractTableModel {
/**
* The list of data that is used in the table.
*/
private List<Student> studentsList;
/**
* A default list of column headers for this table.
*/
private String[] columns = {"Number", "Name", "Email", "Github", "Team"};
/**
* Constructs a new model based on the given list of students.
* @param studentsList A list of students to display in the table model.
*/
public StudentTableModel(List<Student> studentsList) {
this.studentsList = studentsList;
}
/**
* Sets a new list of students as the data for this list model.
* @param newList The new list of students to use.
*/
public void setStudentsList(List<Student> newList) {
this.studentsList = newList;
this.fireTableDataChanged();
}
@Override
public int getRowCount() {
return studentsList.size();
}
@Override
public int getColumnCount() {
return this.columns.length;
}
@Override
public String getColumnName(int i) {
return this.columns[i];
}
@Override
public Object getValueAt(int row, int col) {
Student student = studentsList.get(row);
switch(col) {
case 0:
return student.getNumber();
case 1:
return student.getName();
case 2:
return student.getEmailAddress();
case 3:
return student.getGithubUsername();
case 4:
return student.getAssignedTeam().getId();
default:
return null;
}
}
}

View File

@ -98,7 +98,7 @@ public class TeamGenerator {
// Once we know this team is completely valid, we remove all the students in it from the list of singles.
newTeam.setNumber(teamCount++);
singleStudents.removeAll(Arrays.asList(newTeam.getStudents()));
studentTeams.add(newTeam);
assignStudentsToTeam(newTeam);
logger.fine("Created team:\n" + newTeam);
}
}
@ -128,6 +128,7 @@ public class TeamGenerator {
t.addMember(s);
}
studentTeams.add(t);
assignStudentsToTeam(t);
logger.fine("Created team:\n" + t);
}
return studentTeams;
@ -187,4 +188,15 @@ public class TeamGenerator {
return students;
}
/**
* Assigns all students in the given team to that team, such that all students then have a reference to the team
* they are in.
* @param team The team to assign students for.
*/
private static void assignStudentsToTeam(StudentTeam team) {
for (Student student : team.getStudents()) {
student.assignToTeam(team);
}
}
}