Added some right-click functionality, and made dependencies safe.

This commit is contained in:
Andrew Lalis 2018-10-23 14:19:31 +02:00
parent 134d2ede64
commit a1d23b82ad
12 changed files with 211 additions and 21 deletions

View File

@ -30,12 +30,12 @@
<dependency> <dependency>
<groupId>commons-cli</groupId> <groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId> <artifactId>commons-cli</artifactId>
<version>RELEASE</version> <version>1.4</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>commons-email</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId> <artifactId>commons-email</artifactId>
<version>RELEASE</version> <version>1.5</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.jetbrains</groupId> <groupId>org.jetbrains</groupId>
@ -46,7 +46,7 @@
<dependency> <dependency>
<groupId>org.apache.httpcomponents</groupId> <groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId> <artifactId>httpclient</artifactId>
<version>RELEASE</version> <version>4.5.6</version>
</dependency> </dependency>
<!-- Github API Object Library --> <!-- Github API Object Library -->
<dependency> <dependency>

View File

@ -251,7 +251,7 @@ public class GithubManager {
return; return;
} }
team.setRepository(repo); team.setRepositoryName(repo.getName());
team.setTaTeam(taTeam); team.setTaTeam(taTeam);
this.protectMasterBranch(repo, taTeam.getGithubTeam()); this.protectMasterBranch(repo, taTeam.getGithubTeam());
@ -339,7 +339,7 @@ public class GithubManager {
GHUser user = this.github.getUser(student.getGithubUsername()); GHUser user = this.github.getUser(student.getGithubUsername());
this.addCollaboratorToRepo(user, assignmentsRepo); this.addCollaboratorToRepo(user, assignmentsRepo);
this.addCollaboratorToRepo(user, team.getRepository()); this.addCollaboratorToRepo(user, this.organization.getRepository(team.getRepositoryName()));
} }
} catch (IOException e) { } catch (IOException e) {
logger.severe("Could not add students as collaborators to assignments or their repo.\n" + team); logger.severe("Could not add students as collaborators to assignments or their repo.\n" + team);

View File

@ -21,25 +21,25 @@ public abstract class Person extends BaseEntity implements Detailable {
/** /**
* The unique identification number for this person. (P- or S-Number) * The unique identification number for this person. (P- or S-Number)
*/ */
@Column(name="number") @Column(name="number", nullable = false)
protected int number; protected int number;
/** /**
* The person's first and last name. * The person's first and last name.
*/ */
@Column(name="name") @Column(name="name", nullable = false)
protected String name; protected String name;
/** /**
* The person's email address. * The person's email address.
*/ */
@Column(name="email_address") @Column(name="email_address", nullable = false)
protected String emailAddress; protected String emailAddress;
/** /**
* The person's github username. * The person's github username.
*/ */
@Column(name="github_username") @Column(name="github_username", nullable = false)
protected String githubUsername; protected String githubUsername;
/** /**

View File

@ -1,12 +1,13 @@
package nl.andrewlalis.model; package nl.andrewlalis.model;
import org.kohsuke.github.GHRepository; import nl.andrewlalis.util.Pair;
import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.ManyToOne; import javax.persistence.ManyToOne;
import javax.persistence.Table; import javax.persistence.Table;
import javax.persistence.Transient;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
/** /**
* Represents one or more students' collective information. * Represents one or more students' collective information.
@ -18,8 +19,8 @@ public class StudentTeam extends Team {
/** /**
* The repository belonging to this team. * The repository belonging to this team.
*/ */
@Transient @Column(name = "repository_name", unique = true)
private GHRepository repository; private String repositoryName;
/** /**
* The TATeam responsible for this student team. * The TATeam responsible for this student team.
@ -97,12 +98,12 @@ public class StudentTeam extends Team {
return sb.toString(); return sb.toString();
} }
public GHRepository getRepository() { public String getRepositoryName() {
return this.repository; return this.repositoryName;
} }
public void setRepository(GHRepository repo) { public void setRepositoryName(String repositoryName) {
this.repository = repo; this.repositoryName = repositoryName;
} }
public TATeam getTaTeam() { public TATeam getTaTeam() {
@ -117,4 +118,17 @@ public class StudentTeam extends Team {
public String getDetailName() { public String getDetailName() {
return this.generateRepoDescription(); return this.generateRepoDescription();
} }
@Override
public List<Pair<String, String>> getDetailPairs() {
List<Pair<String, String>> pairs = super.getDetailPairs();
pairs.add(new Pair<>("Repository Name", this.getRepositoryName()));
String taTeamName = "None";
if (this.getTaTeam() != null) {
taTeamName = this.getTaTeam().getDetailName();
}
pairs.add(new Pair<>("TA Team", taTeamName));
return pairs;
}
} }

View File

@ -0,0 +1,42 @@
package nl.andrewlalis.ui.control.listeners.management_view;
import javax.swing.*;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import java.awt.*;
/**
* This listener, when added to a JPopupMenu, will select the clicked row when a user right-clicks on the table.
*/
public class PopupSelector implements PopupMenuListener {
/**
* The table on which to select rows.
*/
private JTable table;
public PopupSelector(JTable table) {
this.table = table;
}
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent popupMenuEvent) {
JPopupMenu popupMenu = (JPopupMenu) popupMenuEvent.getSource();
SwingUtilities.invokeLater(() -> {
int rowAtPoint = table.rowAtPoint(SwingUtilities.convertPoint(popupMenu, new Point(0, 0), table));
if (rowAtPoint > -1) {
table.setRowSelectionInterval(rowAtPoint, rowAtPoint);
}
});
}
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent popupMenuEvent) {
}
@Override
public void popupMenuCanceled(PopupMenuEvent popupMenuEvent) {
}
}

View File

@ -0,0 +1,39 @@
package nl.andrewlalis.ui.control.listeners.management_view;
import javax.swing.*;
import java.awt.event.ActionListener;
/**
* This abstract class defines listeners which listen to tables, that is, a table row is clicked on in the table, and
* that is passed to children.
*/
public abstract class TableRowListener implements ActionListener {
/**
* The table of which to get the row.
*/
private JTable table;
/**
* Constructs a table row listener.
* @param table The table on which to get selected rows.
*/
public TableRowListener(JTable table) {
this.table = table;
}
/**
* @return The selected row.
*/
protected final int getSelectedRow() {
return this.table.getSelectedRow();
}
/**
* @return The table that this listener is attached to.
*/
protected final JTable getTable() {
return this.table;
}
}

View File

@ -0,0 +1,28 @@
package nl.andrewlalis.ui.control.listeners.management_view.student_actions;
import nl.andrewlalis.ui.control.listeners.management_view.TableRowListener;
import nl.andrewlalis.ui.view.table_models.StudentTableModel;
import javax.swing.*;
import java.awt.event.ActionEvent;
/**
* Listens for when the user intends to remove a selected student from the course entirely. This entails a few things:
* 1. Remove them from any team they are in.
* 2. Archive any repository that is empty as a result of removing them.
* 3. Remove the student from the list of students.
* (This should not actually remove the record, just set it as removed.)
*/
public class RemoveFromCourseListener extends TableRowListener {
public RemoveFromCourseListener(JTable table) {
super(table);
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
StudentTableModel model = (StudentTableModel) this.getTable().getModel();
System.out.println(model.getStudentAt(this.getSelectedRow()));
}
}

View File

@ -0,0 +1,31 @@
package nl.andrewlalis.ui.control.listeners.management_view.student_actions;
import nl.andrewlalis.model.Student;
import nl.andrewlalis.model.StudentTeam;
import nl.andrewlalis.ui.control.listeners.management_view.TableRowListener;
import nl.andrewlalis.ui.view.dialogs.TeamChooserDialog;
import nl.andrewlalis.ui.view.table_models.StudentTableModel;
import javax.swing.*;
import java.awt.event.ActionEvent;
/**
* Listens for when the user wishes to set the team of a certain student. This should do the following:
* 1. User selects team to set student to, or chooses to create a new team.
* 2. StudentTeam object is created or modified.
* 3. The repository is updated automatically.
*/
public class SetTeamListener extends TableRowListener {
public SetTeamListener(JTable table) {
super(table);
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
StudentTableModel model = (StudentTableModel) this.getTable().getModel();
Student student = model.getStudentAt(this.getSelectedRow());
StudentTeam chosenTeam = (StudentTeam) new TeamChooserDialog(SwingUtilities.getWindowAncestor(this.getTable())).getSelectedTeam();
}
}

View File

@ -28,6 +28,11 @@ public abstract class AbstractView extends JFrame {
*/ */
private List<AbstractView> parentViews; private List<AbstractView> parentViews;
/**
* The image icon for all abstract views.
*/
private static final ImageIcon imageIcon = new ImageIcon(AbstractView.class.getResource("/image/icon.png"));
/** /**
* Initializes the view by packing the content pane as it is defined by any child, and setting some generic swing * Initializes the view by packing the content pane as it is defined by any child, and setting some generic swing
* values. * values.
@ -42,6 +47,7 @@ public abstract class AbstractView extends JFrame {
this.githubManager = githubManager; this.githubManager = githubManager;
this.childViews = new ArrayList<>(); this.childViews = new ArrayList<>();
this.parentViews = new ArrayList<>(); this.parentViews = new ArrayList<>();
this.setIconImage(imageIcon.getImage());
this.setContentPane(this.buildContentPane()); this.setContentPane(this.buildContentPane());
this.setDefaultCloseOperation(defaultCloseOperation); this.setDefaultCloseOperation(defaultCloseOperation);
if (preferredSize != null) { if (preferredSize != null) {

View File

@ -3,6 +3,8 @@ package nl.andrewlalis.ui.view;
import nl.andrewlalis.git_api.GithubManager; import nl.andrewlalis.git_api.GithubManager;
import nl.andrewlalis.model.database.DbHelper; import nl.andrewlalis.model.database.DbHelper;
import nl.andrewlalis.model.database.DbUtil; import nl.andrewlalis.model.database.DbUtil;
import nl.andrewlalis.ui.control.listeners.management_view.PopupSelector;
import nl.andrewlalis.ui.control.listeners.management_view.student_actions.RemoveFromCourseListener;
import nl.andrewlalis.ui.view.components.DetailPanel; import nl.andrewlalis.ui.view.components.DetailPanel;
import nl.andrewlalis.ui.view.table_models.StudentTableModel; import nl.andrewlalis.ui.view.table_models.StudentTableModel;
import nl.andrewlalis.ui.view.table_models.StudentTeamTableModel; import nl.andrewlalis.ui.view.table_models.StudentTeamTableModel;
@ -145,6 +147,13 @@ public class ManagementView extends AbstractView {
table.getSelectionModel().addListSelectionListener(listSelectionEvent -> { table.getSelectionModel().addListSelectionListener(listSelectionEvent -> {
detailPanel.setDetailableEntity(studentsModel.getStudentAt(table.getSelectedRow())); detailPanel.setDetailableEntity(studentsModel.getStudentAt(table.getSelectedRow()));
}); });
JPopupMenu menu = new JPopupMenu("Menu");
JMenuItem removeItem = new JMenuItem("Remove from course");
removeItem.addActionListener(new RemoveFromCourseListener(table));
menu.add(removeItem);
menu.addPopupMenuListener(new PopupSelector(table));
table.setComponentPopupMenu(menu);
return this.buildGenericTablePanel(table); return this.buildGenericTablePanel(table);
} }

View File

@ -0,0 +1,18 @@
package nl.andrewlalis.ui.view.dialogs;
import nl.andrewlalis.model.Team;
import javax.swing.*;
import java.awt.*;
public class TeamChooserDialog extends JDialog {
public TeamChooserDialog(Window parent) {
super(parent);
}
public Team getSelectedTeam() {
return null;
}
}

View File

@ -21,7 +21,7 @@ public class StudentTeamTableModel extends AbstractTableModel {
* The column headers for this model. In addition to these headers, this model will dynamically create headers for * 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. * each additional student to be listed in the table.
*/ */
private final String[] staticColumns = {"Number", "Member Count"}; private final String[] staticColumns = {"Number", "Repository Name", "TA Team"};
/** /**
* Dynamic columns which are generated depending on the teams. * Dynamic columns which are generated depending on the teams.
@ -90,7 +90,9 @@ public class StudentTeamTableModel extends AbstractTableModel {
case 0: case 0:
return team.getId(); return team.getId();
case 1: case 1:
return team.memberCount(); return (team.getRepositoryName() == null) ? "None" : team.getRepositoryName();
case 2:
return (team.getTaTeam() == null) ? "None" : team.getTaTeam().getDetailName();
default: default:
return this.getMemberInColumn(team, i1); return this.getMemberInColumn(team, i1);
} }
@ -135,8 +137,9 @@ public class StudentTeamTableModel extends AbstractTableModel {
this.columns = new String[this.staticColumns.length + maxMembers]; this.columns = new String[this.staticColumns.length + maxMembers];
this.columns[0] = this.staticColumns[0]; this.columns[0] = this.staticColumns[0];
this.columns[1] = this.staticColumns[1]; this.columns[1] = this.staticColumns[1];
this.columns[2] = this.staticColumns[2];
for (int i = 0; i < maxMembers; i++) { for (int i = 0; i < maxMembers; i++) {
this.columns[i + 2] = "Member " + (i + 1); this.columns[i + this.staticColumns.length] = "Member " + (i + 1);
} }
} }
} }