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

View File

@ -251,7 +251,7 @@ public class GithubManager {
return;
}
team.setRepository(repo);
team.setRepositoryName(repo.getName());
team.setTaTeam(taTeam);
this.protectMasterBranch(repo, taTeam.getGithubTeam());
@ -339,7 +339,7 @@ public class GithubManager {
GHUser user = this.github.getUser(student.getGithubUsername());
this.addCollaboratorToRepo(user, assignmentsRepo);
this.addCollaboratorToRepo(user, team.getRepository());
this.addCollaboratorToRepo(user, this.organization.getRepository(team.getRepositoryName()));
}
} catch (IOException e) {
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)
*/
@Column(name="number")
@Column(name="number", nullable = false)
protected int number;
/**
* The person's first and last name.
*/
@Column(name="name")
@Column(name="name", nullable = false)
protected String name;
/**
* The person's email address.
*/
@Column(name="email_address")
@Column(name="email_address", nullable = false)
protected String emailAddress;
/**
* The person's github username.
*/
@Column(name="github_username")
@Column(name="github_username", nullable = false)
protected String githubUsername;
/**

View File

@ -1,12 +1,13 @@
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.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Transient;
import java.util.Arrays;
import java.util.List;
/**
* Represents one or more students' collective information.
@ -18,8 +19,8 @@ public class StudentTeam extends Team {
/**
* The repository belonging to this team.
*/
@Transient
private GHRepository repository;
@Column(name = "repository_name", unique = true)
private String repositoryName;
/**
* The TATeam responsible for this student team.
@ -97,12 +98,12 @@ public class StudentTeam extends Team {
return sb.toString();
}
public GHRepository getRepository() {
return this.repository;
public String getRepositoryName() {
return this.repositoryName;
}
public void setRepository(GHRepository repo) {
this.repository = repo;
public void setRepositoryName(String repositoryName) {
this.repositoryName = repositoryName;
}
public TATeam getTaTeam() {
@ -117,4 +118,17 @@ public class StudentTeam extends Team {
public String getDetailName() {
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;
/**
* 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
* values.
@ -42,6 +47,7 @@ public abstract class AbstractView extends JFrame {
this.githubManager = githubManager;
this.childViews = new ArrayList<>();
this.parentViews = new ArrayList<>();
this.setIconImage(imageIcon.getImage());
this.setContentPane(this.buildContentPane());
this.setDefaultCloseOperation(defaultCloseOperation);
if (preferredSize != null) {

View File

@ -3,6 +3,8 @@ 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.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.table_models.StudentTableModel;
import nl.andrewlalis.ui.view.table_models.StudentTeamTableModel;
@ -145,6 +147,13 @@ public class ManagementView extends AbstractView {
table.getSelectionModel().addListSelectionListener(listSelectionEvent -> {
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);
}

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
* 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.
@ -90,7 +90,9 @@ public class StudentTeamTableModel extends AbstractTableModel {
case 0:
return team.getId();
case 1:
return team.memberCount();
return (team.getRepositoryName() == null) ? "None" : team.getRepositoryName();
case 2:
return (team.getTaTeam() == null) ? "None" : team.getTaTeam().getDetailName();
default:
return this.getMemberInColumn(team, i1);
}
@ -135,8 +137,9 @@ public class StudentTeamTableModel extends AbstractTableModel {
this.columns = new String[this.staticColumns.length + maxMembers];
this.columns[0] = this.staticColumns[0];
this.columns[1] = this.staticColumns[1];
this.columns[2] = this.staticColumns[2];
for (int i = 0; i < maxMembers; i++) {
this.columns[i + 2] = "Member " + (i + 1);
this.columns[i + this.staticColumns.length] = "Member " + (i + 1);
}
}
}