Implemented a basic detail view.
This commit is contained in:
parent
e57897a005
commit
a2797e54a6
|
@ -3,12 +3,17 @@ package nl.andrewlalis;
|
|||
import nl.andrewlalis.command.CommandExecutor;
|
||||
import nl.andrewlalis.command.executables.*;
|
||||
import nl.andrewlalis.git_api.GithubManager;
|
||||
import nl.andrewlalis.model.StudentTeam;
|
||||
import nl.andrewlalis.model.database.DbHelper;
|
||||
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;
|
||||
import nl.andrewlalis.util.TeamGenerator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
@ -32,6 +37,41 @@ public class Main {
|
|||
// Initialize logger.
|
||||
Logging.setup();
|
||||
|
||||
//startOldVersion(userOptions);
|
||||
|
||||
logger.info("GithubManager for Github Repositories in Educational Organizations.\n" +
|
||||
"© Andrew Lalis (2018), All rights reserved.\n" +
|
||||
"Program initialized.");
|
||||
|
||||
GithubManager manager = new GithubManager();
|
||||
managementView = new ManagementView(manager);
|
||||
|
||||
initializeTestingData();
|
||||
StartView startView = new StartView(manager, "InitializerTesting", userOptions.get("token"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The management view used for the application.
|
||||
*/
|
||||
public static ManagementView getManagementView() {
|
||||
return managementView;
|
||||
}
|
||||
|
||||
private static void initializeTestingData() {
|
||||
try {
|
||||
List<StudentTeam> teams = TeamGenerator.generateFromCSV("/home/andrew/Documents/School/ta/GithubInitializer/sampleAOOP.csv", 2);
|
||||
DbHelper.saveStudentTeams(teams);
|
||||
managementView.updateModels();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Legacy code to run the old version of the application.
|
||||
* @param userOptions The options the user has entered in the command line.
|
||||
*/
|
||||
public static void startOldVersion(Map<String, String> userOptions) {
|
||||
// Command executor which will be used by all actions the user can do.
|
||||
CommandExecutor executor = new CommandExecutor();
|
||||
|
||||
|
@ -50,29 +90,6 @@ public class Main {
|
|||
executor.registerCommand("delegate_student_teams", new DelegateStudentTeams(app));
|
||||
executor.registerCommand("setup_student_repos", new SetupStudentRepos(app));
|
||||
executor.registerCommand("list_repos", new ListRepos());
|
||||
|
||||
logger.info("GithubManager for Github Repositories in Educational Organizations.\n" +
|
||||
"© Andrew Lalis (2018), All rights reserved.\n" +
|
||||
"Program initialized.");
|
||||
|
||||
GithubManager manager = new GithubManager();
|
||||
managementView = new ManagementView(manager);
|
||||
|
||||
// SessionFactory factory = DbUtil.getSessionFactory();
|
||||
// Session session = factory.openSession();
|
||||
// session.beginTransaction();
|
||||
// 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
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.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A generic object that students, teaching assistants, and professors can extend from. This covers all the basic
|
||||
|
@ -12,7 +16,7 @@ import javax.persistence.Table;
|
|||
*/
|
||||
@Entity(name = "Person")
|
||||
@Table(name = "persons")
|
||||
public abstract class Person extends BaseEntity {
|
||||
public abstract class Person extends BaseEntity implements Detailable {
|
||||
|
||||
/**
|
||||
* The unique identification number for this person. (P- or S-Number)
|
||||
|
@ -138,4 +142,24 @@ public abstract class Person extends BaseEntity {
|
|||
public String toString() {
|
||||
return this.getName() + ", " + this.getNumber() + ", " + this.getEmailAddress() + ", " + this.getGithubUsername();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDetailName() {
|
||||
return this.getName() + ", " + this.getNumber();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDetailDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Pair<String, String>> getDetailPairs() {
|
||||
List<Pair<String, String>> pairs = new ArrayList<>();
|
||||
pairs.add(new Pair<>("Name", this.getName()));
|
||||
pairs.add(new Pair<>("Number", String.valueOf(this.getNumber())));
|
||||
pairs.add(new Pair<>("Email Address", this.getEmailAddress()));
|
||||
pairs.add(new Pair<>("Github Username", this.getGithubUsername()));
|
||||
return pairs;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
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;
|
||||
|
||||
|
@ -23,4 +25,22 @@ public class DbHelper {
|
|||
return students;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a list of student teams to the database.
|
||||
*/
|
||||
public static void saveStudentTeams(List<StudentTeam> 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
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.model.database.DbHelper;
|
||||
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;
|
||||
|
@ -42,10 +39,7 @@ public class FileSelectListener implements ActionListener {
|
|||
chooser.addChoosableFileFilter(new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(File file) {
|
||||
if (file.isDirectory()) {
|
||||
return true;
|
||||
}
|
||||
return file.getName().toLowerCase().endsWith(".csv");
|
||||
return file.isDirectory() || file.getName().toLowerCase().endsWith(".csv");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -59,19 +53,7 @@ public class FileSelectListener implements ActionListener {
|
|||
int teamSize = this.fileView.getStudentsPerTeam();
|
||||
try {
|
||||
List<StudentTeam> teams = TeamGenerator.generateFromCSV(chooser.getSelectedFile().getAbsolutePath(), teamSize);
|
||||
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();
|
||||
|
||||
DbHelper.saveStudentTeams(teams);
|
||||
Main.getManagementView().updateModels();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
|
|
|
@ -3,6 +3,7 @@ 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.components.DetailPanel;
|
||||
import nl.andrewlalis.ui.view.table_models.StudentTableModel;
|
||||
|
||||
import javax.swing.*;
|
||||
|
@ -20,6 +21,11 @@ public class ManagementView extends AbstractView {
|
|||
*/
|
||||
private StudentTableModel studentsModel;
|
||||
|
||||
/**
|
||||
* A panel which displays the details of selected entities.
|
||||
*/
|
||||
private DetailPanel detailPanel;
|
||||
|
||||
public ManagementView(GithubManager githubManager) {
|
||||
super(
|
||||
"Course Management",
|
||||
|
@ -30,14 +36,14 @@ public class ManagementView extends AbstractView {
|
|||
);
|
||||
this.setExtendedState(this.getExtendedState() | JFrame.MAXIMIZED_BOTH);
|
||||
|
||||
// Dispose of all parents when this window closes.
|
||||
// Dispose of all parents when this window closes. This is unique to the management view.
|
||||
this.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosed(WindowEvent windowEvent) {
|
||||
for (AbstractView parent : getParentViews()) {
|
||||
parent.dispose();
|
||||
}
|
||||
DbUtil.tearDown();
|
||||
DbUtil.tearDown(); // Shut down the database session factory once everything is done.
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -45,9 +51,12 @@ public class ManagementView extends AbstractView {
|
|||
@Override
|
||||
protected JPanel buildContentPane() {
|
||||
JPanel contentPane = new JPanel(new BorderLayout());
|
||||
contentPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||
|
||||
this.detailPanel = new DetailPanel();
|
||||
|
||||
contentPane.add(this.buildCommandPanel(), BorderLayout.WEST);
|
||||
contentPane.add(this.buildDetailPanel(), BorderLayout.EAST);
|
||||
contentPane.add(this.detailPanel, BorderLayout.EAST);
|
||||
contentPane.add(this.buildOverviewPanel(), BorderLayout.CENTER);
|
||||
|
||||
return contentPane;
|
||||
|
@ -58,6 +67,7 @@ public class ManagementView extends AbstractView {
|
|||
*/
|
||||
private JPanel buildCommandPanel() {
|
||||
JPanel commandPanel = new JPanel(new BorderLayout());
|
||||
commandPanel.setBorder(BorderFactory.createLoweredBevelBorder());
|
||||
|
||||
commandPanel.add(new JLabel("Commands", SwingConstants.CENTER), BorderLayout.NORTH);
|
||||
commandPanel.add(new JTextArea("Command prompt area goes here."), BorderLayout.CENTER);
|
||||
|
@ -72,38 +82,55 @@ public class ManagementView extends AbstractView {
|
|||
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.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||
|
||||
overviewPanel.add(new JLabel("Overview"), BorderLayout.NORTH);
|
||||
overviewPanel.add(new JLabel("Overview", SwingConstants.CENTER), 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);
|
||||
tabbedPane.addTab("Students", this.buildStudentsTablePanel());
|
||||
tabbedPane.addTab("Student Teams", this.buildStudentTeamsTablePanel());
|
||||
tabbedPane.addTab("Teaching Assistants", this.buildTAsTablePanel());
|
||||
|
||||
overviewPanel.add(tabbedPane, BorderLayout.CENTER);
|
||||
|
||||
return overviewPanel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A JPanel to be put into a tab for display of a list of students.
|
||||
*/
|
||||
private JPanel buildStudentsTablePanel() {
|
||||
// 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;
|
||||
}
|
||||
|
||||
private JPanel buildStudentTeamsTablePanel() {
|
||||
return new JPanel();
|
||||
}
|
||||
|
||||
private JPanel buildTAsTablePanel() {
|
||||
return new JPanel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates all models in the management view in accordance with the database.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
package nl.andrewlalis.ui.view.components;
|
||||
|
||||
import nl.andrewlalis.ui.view.table_models.DetailPairsModel;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* The detail panel is meant for displaying the details of a specific entity. The actual content/details to display is
|
||||
* given by classes which implement the Detailable interface.
|
||||
*/
|
||||
public class DetailPanel extends JPanel {
|
||||
|
||||
/**
|
||||
* The name field shows the entity's name.
|
||||
*/
|
||||
private JTextField nameField;
|
||||
|
||||
/**
|
||||
* The description area shows the entity's description.
|
||||
*/
|
||||
private JTextArea descriptionTextArea;
|
||||
|
||||
/**
|
||||
* A model to represent the key-value pairs of this entity.
|
||||
*/
|
||||
private DetailPairsModel detailPairsModel;
|
||||
|
||||
/**
|
||||
* Creates the panel with some basic empty components.
|
||||
*/
|
||||
public DetailPanel() {
|
||||
super();
|
||||
this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
|
||||
this.add(new JLabel("Details", SwingConstants.CENTER));
|
||||
this.add(this.buildNamePanel());
|
||||
this.add(this.buildDescriptionPanel());
|
||||
this.add(this.buildPairsTablePanel());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this panel's properties according to the given entity.
|
||||
* @param entity The entity to get details from.
|
||||
*/
|
||||
public void setDetailableEntity(Detailable entity) {
|
||||
this.nameField.setText(entity.getDetailName());
|
||||
this.descriptionTextArea.setText(entity.getDetailDescription());
|
||||
this.detailPairsModel.setPairs(entity.getDetailPairs());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A JPanel containing the name field.
|
||||
*/
|
||||
private JPanel buildNamePanel() {
|
||||
this.nameField = new JTextField();
|
||||
this.nameField.setEditable(false);
|
||||
|
||||
JPanel namePanel = new JPanel(new BorderLayout());
|
||||
namePanel.add(new JLabel("Name:", SwingConstants.LEFT), BorderLayout.WEST);
|
||||
namePanel.add(this.nameField, BorderLayout.CENTER);
|
||||
|
||||
return namePanel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A JPanel containing the description text area.
|
||||
*/
|
||||
private JPanel buildDescriptionPanel() {
|
||||
this.descriptionTextArea = new JTextArea();
|
||||
this.descriptionTextArea.setEditable(false);
|
||||
|
||||
JPanel descriptionPanel = new JPanel(new BorderLayout());
|
||||
descriptionPanel.add(new JLabel("Description:", SwingConstants.CENTER), BorderLayout.NORTH);
|
||||
descriptionPanel.add(this.descriptionTextArea, BorderLayout.CENTER);
|
||||
|
||||
return descriptionPanel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A JPanel containing a table of properties.
|
||||
*/
|
||||
private JPanel buildPairsTablePanel() {
|
||||
this.detailPairsModel = new DetailPairsModel();
|
||||
|
||||
JPanel tablePanel = new JPanel(new BorderLayout());
|
||||
tablePanel.add(new JLabel("Properties:", SwingConstants.LEFT), BorderLayout.NORTH);
|
||||
|
||||
JTable pairsTable = new JTable(this.detailPairsModel);
|
||||
JScrollPane scrollPane = new JScrollPane(pairsTable);
|
||||
tablePanel.add(scrollPane, BorderLayout.CENTER);
|
||||
|
||||
return tablePanel;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package nl.andrewlalis.ui.view.components;
|
||||
|
||||
import nl.andrewlalis.util.Pair;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Objects which implement this interface must provide
|
||||
*/
|
||||
public interface Detailable {
|
||||
|
||||
/**
|
||||
* @return The display name for this object.
|
||||
*/
|
||||
String getDetailName();
|
||||
|
||||
/**
|
||||
* @return Some more information to display below the name for this object.
|
||||
*/
|
||||
String getDetailDescription();
|
||||
|
||||
/**
|
||||
* @return A String-to-String mapping for some key value pairs of properties to display.
|
||||
*/
|
||||
List<Pair<String, String>> getDetailPairs();
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package nl.andrewlalis.ui.view.table_models;
|
||||
|
||||
import nl.andrewlalis.util.Pair;
|
||||
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents the small (2 column) table to display properties of a detailable entity.
|
||||
*/
|
||||
public class DetailPairsModel extends AbstractTableModel {
|
||||
|
||||
/**
|
||||
* The pairs of properties.
|
||||
*/
|
||||
private List<Pair<String, String>> pairs;
|
||||
|
||||
/**
|
||||
* Columns for this model.
|
||||
*/
|
||||
private String[] columns = {"Property", "Value"};
|
||||
|
||||
/**
|
||||
* Constructs an empty list of pairs.
|
||||
*/
|
||||
public DetailPairsModel() {
|
||||
this.pairs = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void setPairs(List<Pair<String, String>> pairs) {
|
||||
this.pairs = pairs;
|
||||
this.fireTableDataChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
return this.pairs.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return this.columns.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName(int i) {
|
||||
return this.columns[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int i, int i1) {
|
||||
Pair pair = this.pairs.get(i);
|
||||
|
||||
switch (i1) {
|
||||
case 0:
|
||||
return pair.getFirst();
|
||||
case 1:
|
||||
return pair.getSecond();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -37,6 +37,15 @@ public class StudentTableModel extends AbstractTableModel {
|
|||
this.fireTableDataChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the student in a particular row.
|
||||
* @param row The row of the table.
|
||||
* @return The student object at the specified row, or null if none is found.
|
||||
*/
|
||||
public Student getStudentAt(int row) {
|
||||
return this.studentsList.get(row);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
return studentsList.size();
|
||||
|
@ -54,7 +63,7 @@ public class StudentTableModel extends AbstractTableModel {
|
|||
|
||||
@Override
|
||||
public Object getValueAt(int row, int col) {
|
||||
Student student = studentsList.get(row);
|
||||
Student student = this.getStudentAt(row);
|
||||
|
||||
switch(col) {
|
||||
case 0:
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package nl.andrewlalis.util;
|
||||
|
||||
/**
|
||||
* A pair of objects.
|
||||
* @param <T1> The first object.
|
||||
* @param <T2> The second object.
|
||||
*/
|
||||
public class Pair<T1, T2> {
|
||||
|
||||
private T1 first;
|
||||
private T2 second;
|
||||
|
||||
public Pair(T1 first, T2 second) {
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
public T1 getFirst() {
|
||||
return first;
|
||||
}
|
||||
|
||||
public T2 getSecond() {
|
||||
return second;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue