GitBucket
4.21.2
Toggle navigation
Snippets
Sign in
Files
Branches
1
Releases
Issues
4
Pull requests
Labels
Priorities
Milestones
Wiki
Forks
mark.george
/
marking
Browse code
Added batch email, and sent indicator. Closes
#1
, Closes
#6
.
1 parent
f36b455
commit
68f7c6914725b544004aa4dc7b815dd1a5bc36aa
Mark George
authored
on 3 Nov 2017
Patch
Showing
6 changed files
src/model/Student.java
src/report/Batcher.java
src/report/FeedbackReportGenerator.java
src/report/SendReport.java
src/ui/SubmissionFrame.form
src/ui/SubmissionFrame.java
Ignore Space
Show notes
View
src/model/Student.java
package model; /** * * @author Mark George <mark.george@otago.ac.nz> */ public class Student { private String id; private String userName; private String name; private String email; private Boolean sendFeedback; private Boolean emailSent; public Student() { } public Student(String id, String userName, String name, String email, Boolean sendFeedback, Boolean emailSent) { this.id = id; this.userName = userName; this.name = name; this.email = email; this.sendFeedback = sendFeedback; this.emailSent = emailSent; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Boolean getSendFeedback() { return sendFeedback; } public void setSendFeedback(Boolean sendFeedback) { this.sendFeedback = sendFeedback; } public Boolean getEmailSent() { return emailSent; } public void setEmailSent(Boolean emailSent) { this.emailSent = emailSent; } }
package model; /** * * @author Mark George <mark.george@otago.ac.nz> */ public class Student { private Integer id; private String userName; private String name; private String email; public Student() { } public Student(Integer id, String userName, String name) { this.id = id; this.userName = userName; this.name = name; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
Ignore Space
Show notes
View
src/report/Batcher.java
0 → 100644
package report; import dao.MarkingProperties; import dao.ResultDAO; import java.util.Collection; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; import model.Student; /** * * @author mark */ public class Batcher { public void batch() { Collection<Student> students = new ResultDAO().getStudents(); for (Student student : students) { if (!student.getSendFeedback() || student.getEmailSent()) { continue; } new FeedbackReportGenerator(new ResultDAO().getResult(student.getUserName()), MarkingProperties.reportPath(), MarkingProperties.attachmentFilePrefix()).generate(student); String report = MarkingProperties.reportPath() + "/" + MarkingProperties.attachmentFilePrefix() + "-" + student.getId() + ".pdf"; if (MarkingProperties.isEmailEnabled()) { new SendReport().sendReport(student, report); try { TimeUnit.SECONDS.sleep(1); // short delay to avoid triggering rate limiting } catch (InterruptedException ex) { Logger.getLogger(Batcher.class.getName()).log(Level.SEVERE, null, ex); } } } } }
Ignore Space
Show notes
View
src/report/FeedbackReportGenerator.java
package report; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.math.BigDecimal; import java.util.Collection; import java.util.Map; import model.Student; import static net.sf.dynamicreports.report.builder.DynamicReports.cmp; import static net.sf.dynamicreports.report.builder.DynamicReports.field; import static net.sf.dynamicreports.report.builder.DynamicReports.grp; import static net.sf.dynamicreports.report.builder.DynamicReports.margin; import static net.sf.dynamicreports.report.builder.DynamicReports.report; import static net.sf.dynamicreports.report.builder.DynamicReports.stl; import static net.sf.dynamicreports.report.builder.DynamicReports.template; import static net.sf.dynamicreports.report.builder.DynamicReports.type; import net.sf.dynamicreports.report.builder.FieldBuilder; import net.sf.dynamicreports.report.builder.group.CustomGroupBuilder; import net.sf.dynamicreports.report.builder.style.StyleBuilder; import net.sf.dynamicreports.report.constant.HorizontalTextAlignment; import net.sf.dynamicreports.report.constant.LineStyle; import net.sf.dynamicreports.report.constant.VerticalTextAlignment; import net.sf.dynamicreports.report.exception.DRException; import net.sf.jasperreports.engine.data.JRMapCollectionDataSource; /** * * @author Mark George <mark.george@otago.ac.nz> */ public class FeedbackReportGenerator { private final Collection<Map<String, ?>> data; private final String outputDirectory; private final String fileNamePrefix; public FeedbackReportGenerator(Collection<Map<String, ?>> data, String outputDirectory, String fileNamePrefix) { this.data = data; this.outputDirectory = outputDirectory; this.fileNamePrefix = fileNamePrefix; } public void generate(Student student) { StyleBuilder labelSty = stl.style() .bold() .setHorizontalTextAlignment(HorizontalTextAlignment.RIGHT) .setVerticalTextAlignment(VerticalTextAlignment.MIDDLE); StyleBuilder valSty = stl.style() .setHorizontalTextAlignment(HorizontalTextAlignment.LEFT) .setVerticalTextAlignment(VerticalTextAlignment.MIDDLE); StyleBuilder markSty = stl.style() .bold() .setHorizontalTextAlignment(HorizontalTextAlignment.RIGHT) .setVerticalTextAlignment(VerticalTextAlignment.MIDDLE); StyleBuilder criterionSty = stl.style() .bold() .setHorizontalTextAlignment(HorizontalTextAlignment.LEFT) .setVerticalTextAlignment(VerticalTextAlignment.MIDDLE); FieldBuilder<String> assessment = field("ASSESSMENT", type.stringType()); FieldBuilder<BigDecimal> outOf = field("OUTOF", type.bigDecimalType()); FieldBuilder<String> id = field("STUDENTID", type.stringType()); FieldBuilder<String> name = field("NAME", type.stringType()); FieldBuilder<BigDecimal> mark = field("MARK", type.bigDecimalType()); FieldBuilder<String> category = field("CATEGORY", type.stringType()); CustomGroupBuilder categoryGroup = grp.group(category).setStyle(stl.style().bold().setFontSize(12)); FieldBuilder<String> criterion = field("CRITERION", type.stringType()); FieldBuilder<BigDecimal> result = field("RESULT", type.bigDecimalType()); FieldBuilder<BigDecimal> max = field("MAX", type.bigDecimalType()); FieldBuilder<String> comment = field("COMMENT", type.stringType()); try { // header report() .setTemplate(template().setPageMargin(margin(50))) .setDataSource(new JRMapCollectionDataSource(data)) .title( cmp.text("INFO202: Developing Information Systems 2 – Assessment Feedback").setStyle(stl.style().setFontSize(14).bold()), cmp.verticalGap(10), cmp.horizontalList() .add( cmp.text("Assessment:").setStyle(labelSty).setWidth(15), cmp.horizontalGap(5), cmp.text(assessment).setStyle(valSty) ) .newRow().add( cmp.text("ID:").setStyle(labelSty).setWidth(15), cmp.horizontalGap(5), cmp.text(id).setStyle(valSty) ) .newRow().add( cmp.text("Name:").setStyle(labelSty).setWidth(15), cmp.horizontalGap(5), cmp.text(name).setStyle(valSty) ) .newRow().add( cmp.text("Mark:").setStyle(labelSty).setWidth(15), cmp.horizontalGap(5), cmp.text(mark).setStyle(valSty) ) .newRow().add( cmp.text("Out of:").setStyle(labelSty).setWidth(15), cmp.horizontalGap(5), cmp.text(outOf).setStyle(valSty) ), cmp.verticalGap(15) ) // details .groupBy(categoryGroup).groupHeader(categoryGroup, cmp.line().setPen(stl.pen(2.0f, LineStyle.DOUBLE))) .detail( cmp.verticalGap(1), cmp.horizontalList() .add( cmp.text(criterion).setStyle(criterionSty).setWidth(50), cmp.text(result).setStyle(markSty).setWidth(4), cmp.text("/").setStyle(labelSty).setWidth(1), cmp.horizontalGap(5), cmp.text(max).setStyle(valSty).setWidth(3) ), cmp.horizontalList( cmp.horizontalGap(11), cmp.text(comment).removeLineWhenBlank() ).setMinHeight(0), cmp.verticalGap(1), cmp.line().setPen(stl.penThin()) ) .groupFooter(categoryGroup, cmp.verticalGap(15)) .summary(cmp.text("Your mark is calculated by dividing the mark for each criterion by the maximum for that criterion, then multiplying by a weight (not shown in this report, but available on request), and then adding all of the weighted marks together. The weightings are based on the size, complexity, and importance of the criterion.")) // .summary(cmp.text("The mark for the bonus tasks is only applied if you lost marks in other components (including the UML diagrams and security audit). In other words, your total mark is capped at 25.")) .pageFooter(cmp.pageXofY().setStyle(stl.style().bold())) // .show() .toPdf(new FileOutputStream(outputDirectory + "/" + fileNamePrefix + "-" + student.getId() + ".pdf")); } catch (FileNotFoundException | DRException ex) { throw new RuntimeException(ex); } } }
package report; import java.io.FileOutputStream; import java.math.BigDecimal; import java.util.Collection; import java.util.Map; import model.Student; import static net.sf.dynamicreports.report.builder.DynamicReports.cmp; import static net.sf.dynamicreports.report.builder.DynamicReports.field; import static net.sf.dynamicreports.report.builder.DynamicReports.grp; import static net.sf.dynamicreports.report.builder.DynamicReports.margin; import static net.sf.dynamicreports.report.builder.DynamicReports.report; import static net.sf.dynamicreports.report.builder.DynamicReports.stl; import static net.sf.dynamicreports.report.builder.DynamicReports.template; import static net.sf.dynamicreports.report.builder.DynamicReports.type; import net.sf.dynamicreports.report.builder.FieldBuilder; import net.sf.dynamicreports.report.builder.group.CustomGroupBuilder; import net.sf.dynamicreports.report.builder.style.StyleBuilder; import net.sf.dynamicreports.report.constant.HorizontalTextAlignment; import net.sf.dynamicreports.report.constant.LineStyle; import net.sf.dynamicreports.report.constant.VerticalTextAlignment; import net.sf.jasperreports.engine.data.JRMapCollectionDataSource; /** * * @author Mark George <mark.george@otago.ac.nz> */ public class FeedbackReportGenerator { private final Collection<Map<String, ?>> data; private final String outputDirectory; private final String fileNamePrefix; public FeedbackReportGenerator(Collection<Map<String, ?>> data, String outputDirectory, String fileNamePrefix) { this.data = data; this.outputDirectory = outputDirectory; this.fileNamePrefix = fileNamePrefix; } public void generate(Student student) throws Exception { StyleBuilder labelSty = stl.style() .bold() .setHorizontalTextAlignment(HorizontalTextAlignment.RIGHT) .setVerticalTextAlignment(VerticalTextAlignment.MIDDLE); StyleBuilder valSty = stl.style() .setHorizontalTextAlignment(HorizontalTextAlignment.LEFT) .setVerticalTextAlignment(VerticalTextAlignment.MIDDLE); StyleBuilder markSty = stl.style() .bold() .setHorizontalTextAlignment(HorizontalTextAlignment.RIGHT) .setVerticalTextAlignment(VerticalTextAlignment.MIDDLE); StyleBuilder criterionSty = stl.style() .bold() .setHorizontalTextAlignment(HorizontalTextAlignment.LEFT) .setVerticalTextAlignment(VerticalTextAlignment.MIDDLE); FieldBuilder<String> assessment = field("ASSESSMENT", type.stringType()); FieldBuilder<BigDecimal> outOf = field("OUTOF", type.bigDecimalType()); FieldBuilder<String> id = field("STUDENTID", type.stringType()); FieldBuilder<String> name = field("NAME", type.stringType()); FieldBuilder<BigDecimal> mark = field("MARK", type.bigDecimalType()); FieldBuilder<String> category = field("CATEGORY", type.stringType()); CustomGroupBuilder categoryGroup = grp.group(category).setStyle(stl.style().bold().setFontSize(12)); FieldBuilder<String> criterion = field("CRITERION", type.stringType()); FieldBuilder<BigDecimal> result = field("RESULT", type.bigDecimalType()); FieldBuilder<BigDecimal> max = field("MAX", type.bigDecimalType()); FieldBuilder<String> comment = field("COMMENT", type.stringType()); // header report() .setTemplate(template().setPageMargin(margin(50))) .setDataSource(new JRMapCollectionDataSource(data)) .title( cmp.text("INFO202: Developing Information Systems 2 – Assessment Feedback").setStyle(stl.style().setFontSize(14).bold()), cmp.verticalGap(10), cmp.horizontalList() .add( cmp.text("Assessment:").setStyle(labelSty).setWidth(15), cmp.horizontalGap(5), cmp.text(assessment).setStyle(valSty) ) .newRow().add( cmp.text("ID:").setStyle(labelSty).setWidth(15), cmp.horizontalGap(5), cmp.text(id).setStyle(valSty) ) .newRow().add( cmp.text("Name:").setStyle(labelSty).setWidth(15), cmp.horizontalGap(5), cmp.text(name).setStyle(valSty) ) .newRow().add( cmp.text("Mark:").setStyle(labelSty).setWidth(15), cmp.horizontalGap(5), cmp.text(mark).setStyle(valSty) ) .newRow().add( cmp.text("Out of:").setStyle(labelSty).setWidth(15), cmp.horizontalGap(5), cmp.text(outOf).setStyle(valSty) ), cmp.verticalGap(15) ) // details .groupBy(categoryGroup).groupHeader(categoryGroup, cmp.line().setPen(stl.pen(2.0f, LineStyle.DOUBLE))) .detail( cmp.verticalGap(1), cmp.horizontalList() .add( cmp.text(criterion).setStyle(criterionSty).setWidth(50), cmp.text(result).setStyle(markSty).setWidth(4), cmp.text("/").setStyle(labelSty).setWidth(1), cmp.horizontalGap(5), cmp.text(max).setStyle(valSty).setWidth(3) ), cmp.horizontalList( cmp.horizontalGap(11), cmp.text(comment).removeLineWhenBlank() ).setMinHeight(0), cmp.verticalGap(1), cmp.line().setPen(stl.penThin()) ) .groupFooter(categoryGroup, cmp.verticalGap(15)) .summary(cmp.text("Your mark is calculated by dividing the mark for each criterion by the maximum for that criterion, then multiplying by a weight (not shown in this report, but available on request), and then adding all of the weighted marks together. The weightings are based on the size, complexity, and importance of the criterion.")) // .summary(cmp.text("The mark for the bonus tasks is only applied if you lost marks in other components (including the UML diagrams and security audit). In other words, your total mark is capped at 25.")) .pageFooter(cmp.pageXofY().setStyle(stl.style().bold())) // .show() .toPdf(new FileOutputStream(outputDirectory + "/" + fileNamePrefix + "-" + student.getId() + ".pdf")); } }
Ignore Space
Show notes
View
src/report/SendReport.java
package report; import dao.MarkingProperties; import dao.ResultDAO; import javax.activation.FileDataSource; import javax.swing.JOptionPane; import javax.swing.JPasswordField; import model.Student; import org.simplejavamail.email.Email; import org.simplejavamail.email.EmailBuilder; import org.simplejavamail.mailer.Mailer; import org.simplejavamail.mailer.config.TransportStrategy; /** * * @author Mark George <mark.george@otago.ac.nz> */ public class SendReport { private static String password = null; public void sendReport(Student student, String reportFileName) { String assessment = MarkingProperties.assessmentDescription(); String file = MarkingProperties.attachmentEmailName(); String mName = MarkingProperties.markerName(); String mEmail = MarkingProperties.markerEmail(); String message = "Hi " + student.getName() + ".\n" + "\n" + "Here is our feedback from marking your INFO202 " + assessment + " submission. The feedback is in the attached PDF document.\n" + "\n" + "Cheers,\n" + mName; Email email = new EmailBuilder() .from(mName, mEmail) .to(student.getEmail()) .cc("mark.george@otago.ac.nz") .subject("INFO202 " + assessment + " Result") .text(message) .build(); email.addAttachment(file, new FileDataSource(reportFileName)); try { String userName = MarkingProperties.smtpUserName(); if (password == null && userName != null) { String result = getPassword("Staff E-Mail Password"); if (result != null) { password = result; } else { System.out.println("Cancelled"); return; } } new Mailer(MarkingProperties.smtpHost(), MarkingProperties.smtpPort(), userName, password, TransportStrategy.SMTP_TLS).sendMail(email); new ResultDAO().mailSent(student); } catch (Exception ex) { JOptionPane.showMessageDialog(null, "Error sending email - password wrong?", "Mail Error", JOptionPane.ERROR_MESSAGE); password = null; ex.printStackTrace(); } } public static String getPassword(String prompt) { JPasswordField txtPasswd = new JPasswordField(); int resp = JOptionPane.showConfirmDialog(null, txtPasswd, prompt, JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); if (resp == JOptionPane.OK_OPTION) { return new String(txtPasswd.getPassword()); } return null; } }
package report; import dao.MarkingProperties; import javax.activation.FileDataSource; import javax.swing.JOptionPane; import javax.swing.JPasswordField; import model.Student; import org.simplejavamail.email.Email; import org.simplejavamail.email.EmailBuilder; import org.simplejavamail.mailer.Mailer; import org.simplejavamail.mailer.config.TransportStrategy; /** * * @author Mark George <mark.george@otago.ac.nz> */ public class SendReport { private static String password = null; public void sendReport(Student student, String reportFileName) { String assessment = MarkingProperties.assessmentDescription(); String file = MarkingProperties.attachmentEmailName(); String message = "Hi " + student.getName() + ".\n" + "\n" + "Here is our feedback from marking your INFO202 " + assessment + " project. The feedback is in the attached PDF document.\n" + "\n" + "Cheers,\n" + "Mark"; Email email = new EmailBuilder() .from("Mark George", "mark.george@otago.ac.nz") .to(student.getEmail()) .cc("mark.george@otago.ac.nz") .subject("INFO202 " + assessment + " Result") .text(message) .build(); email.addAttachment(file, new FileDataSource(reportFileName)); try { String userName = MarkingProperties.smtpUserName(); if (password == null) { String result = getPassword("Staff E-Mail Password"); if (result != null) { password = result; new Mailer(MarkingProperties.smtpHost(), MarkingProperties.smtpPort(), userName, password, TransportStrategy.SMTP_TLS).sendMail(email); } } else { new Mailer(MarkingProperties.smtpHost(), MarkingProperties.smtpPort(), userName, password, TransportStrategy.SMTP_TLS).sendMail(email); } } catch (Exception ex) { JOptionPane.showMessageDialog(null, "Error sending email - password wrong?", "Mail Error", JOptionPane.ERROR_MESSAGE); password = null; } } public static String getPassword(String prompt) { JPasswordField txtPasswd = new JPasswordField(); int resp = JOptionPane.showConfirmDialog(null, txtPasswd, prompt, JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); if (resp == JOptionPane.OK_OPTION) { return new String(txtPasswd.getPassword()); } return null; } }
Ignore Space
Show notes
View
src/ui/SubmissionFrame.form
<?xml version="1.0" encoding="UTF-8" ?> <Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JFrameFormInfo"> <Properties> <Property name="defaultCloseOperation" type="int" value="2"/> <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Dimension value="[300, 800]"/> </Property> </Properties> <SyntheticProperties> <SyntheticProperty name="formSizePolicy" type="int" value="1"/> <SyntheticProperty name="generateCenter" type="boolean" value="false"/> </SyntheticProperties> <AuxValues> <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> </AuxValues> <Layout> <DimensionLayout dim="0"> <Group type="103" groupAlignment="0" attributes="0"> <Group type="102" attributes="0"> <EmptySpace min="-2" max="-2" attributes="0"/> <Group type="103" groupAlignment="0" attributes="0"> <Component id="scrollPane" max="32767" attributes="0"/> <Group type="102" attributes="0"> <Component id="btnQuit" linkSize="3" min="-2" max="-2" attributes="0"/> <EmptySpace type="separate" max="32767" attributes="0"/> <Component id="btnBatch" linkSize="3" min="-2" max="-2" attributes="0"/> <EmptySpace type="separate" max="32767" attributes="0"/> <Component id="btnMark" linkSize="3" min="-2" max="-2" attributes="0"/> </Group> </Group> <EmptySpace min="-2" max="-2" attributes="0"/> </Group> </Group> </DimensionLayout> <DimensionLayout dim="1"> <Group type="103" groupAlignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0"> <EmptySpace min="-2" max="-2" attributes="0"/> <Component id="scrollPane" pref="251" max="32767" attributes="0"/> <EmptySpace type="separate" min="-2" max="-2" attributes="0"/> <Group type="103" groupAlignment="3" attributes="0"> <Component id="btnMark" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="btnQuit" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="btnBatch" alignment="3" min="-2" max="-2" attributes="0"/> </Group> <EmptySpace min="-2" max="-2" attributes="0"/> </Group> </Group> </DimensionLayout> </Layout> <SubComponents> <Container class="javax.swing.JScrollPane" name="scrollPane"> <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> <SubComponents> <Component class="javax.swing.JTable" name="table"> <Events> <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="tableMouseClicked"/> <EventHandler event="keyPressed" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="tableKeyPressed"/> </Events> </Component> </SubComponents> </Container> <Component class="javax.swing.JButton" name="btnMark"> <Properties> <Property name="text" type="java.lang.String" value="Mark Selected Student"/> </Properties> <Events> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnMarkActionPerformed"/> </Events> </Component> <Component class="javax.swing.JButton" name="btnQuit"> <Properties> <Property name="text" type="java.lang.String" value="Quit"/> </Properties> <Events> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnQuitActionPerformed"/> </Events> </Component> <Component class="javax.swing.JButton" name="btnBatch"> <Properties> <Property name="text" type="java.lang.String" value="Batch Report/Email"/> </Properties> <Events> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnBatchActionPerformed"/> </Events> </Component> </SubComponents> </Form>
<?xml version="1.0" encoding="UTF-8" ?> <Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JFrameFormInfo"> <Properties> <Property name="defaultCloseOperation" type="int" value="2"/> <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Dimension value="[300, 800]"/> </Property> </Properties> <SyntheticProperties> <SyntheticProperty name="formSizePolicy" type="int" value="1"/> <SyntheticProperty name="generateCenter" type="boolean" value="false"/> </SyntheticProperties> <AuxValues> <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/> <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> </AuxValues> <Layout> <DimensionLayout dim="0"> <Group type="103" groupAlignment="0" attributes="0"> <Group type="102" attributes="0"> <EmptySpace max="-2" attributes="0"/> <Group type="103" groupAlignment="0" attributes="0"> <Component id="scrollPane" pref="376" max="32767" attributes="0"/> <Group type="102" attributes="0"> <Component id="btnQuit" min="-2" max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/> <Component id="btnMark" max="32767" attributes="0"/> </Group> </Group> <EmptySpace max="-2" attributes="0"/> </Group> </Group> </DimensionLayout> <DimensionLayout dim="1"> <Group type="103" groupAlignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0"> <EmptySpace min="-2" max="-2" attributes="0"/> <Component id="scrollPane" pref="251" max="32767" attributes="0"/> <EmptySpace type="separate" min="-2" max="-2" attributes="0"/> <Group type="103" groupAlignment="3" attributes="0"> <Component id="btnMark" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="btnQuit" alignment="3" min="-2" max="-2" attributes="0"/> </Group> <EmptySpace min="-2" max="-2" attributes="0"/> </Group> </Group> </DimensionLayout> </Layout> <SubComponents> <Container class="javax.swing.JScrollPane" name="scrollPane"> <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> <SubComponents> <Component class="javax.swing.JTable" name="table"> <Properties> <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor"> <Table columnCount="2" rowCount="4"> <Column editable="false" title="Submission" type="java.lang.String"/> <Column editable="false" title="Raw Mark" type="java.lang.Double"/> </Table> </Property> </Properties> <Events> <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="tableMouseClicked"/> <EventHandler event="keyPressed" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="tableKeyPressed"/> </Events> </Component> </SubComponents> </Container> <Component class="javax.swing.JButton" name="btnMark"> <Properties> <Property name="text" type="java.lang.String" value="Mark Selected Student"/> </Properties> <Events> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnMarkActionPerformed"/> </Events> </Component> <Component class="javax.swing.JButton" name="btnQuit"> <Properties> <Property name="text" type="java.lang.String" value="Quit"/> </Properties> <Events> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnQuitActionPerformed"/> </Events> </Component> </SubComponents> </Form>
Ignore Space
Show notes
View
src/ui/SubmissionFrame.java
package ui; import dao.ResultDAO; import dao.ScheduleDAO; import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.StringSelection; import java.awt.event.KeyEvent; import javax.swing.JOptionPane; import report.Batcher; /** * * @author mark */ public class SubmissionFrame extends javax.swing.JFrame { private final ScheduleDAO scheduleDAO = new ScheduleDAO(); private Integer selectedRow = 0; /** * Creates new form SubmissionDialog */ public SubmissionFrame() { initComponents(); table.setModel(new ResultDAO().getSubmissions()); this.setTitle(scheduleDAO.getAssessmentName() + " (" + scheduleDAO.getComplete() + "% marked)"); } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { scrollPane = new javax.swing.JScrollPane(); table = new javax.swing.JTable(); btnMark = new javax.swing.JButton(); btnQuit = new javax.swing.JButton(); btnBatch = new javax.swing.JButton(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setPreferredSize(new java.awt.Dimension(300, 800)); table.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { tableMouseClicked(evt); } }); table.addKeyListener(new java.awt.event.KeyAdapter() { public void keyPressed(java.awt.event.KeyEvent evt) { tableKeyPressed(evt); } }); scrollPane.setViewportView(table); btnMark.setText("Mark Selected Student"); btnMark.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnMarkActionPerformed(evt); } }); btnQuit.setText("Quit"); btnQuit.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnQuitActionPerformed(evt); } }); btnBatch.setText("Batch Report/Email"); btnBatch.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnBatchActionPerformed(evt); } }); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(scrollPane) .addGroup(layout.createSequentialGroup() .addComponent(btnQuit) .addGap(18, 18, Short.MAX_VALUE) .addComponent(btnBatch) .addGap(18, 18, Short.MAX_VALUE) .addComponent(btnMark))) .addContainerGap()) ); layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {btnBatch, btnMark, btnQuit}); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 251, Short.MAX_VALUE) .addGap(18, 18, 18) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(btnMark) .addComponent(btnQuit) .addComponent(btnBatch)) .addContainerGap()) ); pack(); }// </editor-fold>//GEN-END:initComponents private void btnQuitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnQuitActionPerformed System.exit(0); }//GEN-LAST:event_btnQuitActionPerformed private void btnMarkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMarkActionPerformed markSelected(); }//GEN-LAST:event_btnMarkActionPerformed private void tableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tableMouseClicked if (evt.getClickCount() >= 2) { markSelected(); } }//GEN-LAST:event_tableMouseClicked private void tableKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_tableKeyPressed if (evt.getKeyCode() == KeyEvent.VK_ENTER) { evt.consume(); markSelected(); } }//GEN-LAST:event_tableKeyPressed private void btnBatchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnBatchActionPerformed int confirm = JOptionPane.showConfirmDialog(this, "Batch generate and send reports?", "Confirm Batch Operation", JOptionPane.OK_CANCEL_OPTION); if (confirm == JOptionPane.OK_OPTION) { new Batcher().batch(); JOptionPane.showMessageDialog(this, "Done!"); refresh(); } }//GEN-LAST:event_btnBatchActionPerformed private void markSelected() { // get selected ID from table selectedRow = table.getSelectedRow(); String id = (String) table.getModel().getValueAt(selectedRow, 0); // copy selected ID to clipboard StringSelection stringSelection = new StringSelection(id); Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard(); clpbrd.setContents(stringSelection, null); MarkingFrame frame = new MarkingFrame(this, scheduleDAO.getAssessmentName()); // load data into frame ScheduleDAO dao = new ScheduleDAO(); for (String cat : dao.getCategories()) { frame.addCategory(cat, dao.getCriteria(cat)); } frame.load(id); frame.display(); } public void refresh() { // refresh table to display new mark table.setModel(new ResultDAO().getSubmissions()); // update title to show latest completion % this.setTitle(scheduleDAO.getAssessmentName() + " (" + scheduleDAO.getComplete() + "% marked)"); // reselect the most recently selected row table.setRowSelectionInterval(selectedRow, selectedRow); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton btnBatch; private javax.swing.JButton btnMark; private javax.swing.JButton btnQuit; private javax.swing.JScrollPane scrollPane; private javax.swing.JTable table; // End of variables declaration//GEN-END:variables }
package ui; import dao.ResultDAO; import dao.ScheduleDAO; import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.StringSelection; import java.awt.event.KeyEvent; /** * * @author mark */ public class SubmissionFrame extends javax.swing.JFrame { private final ScheduleDAO scheduleDAO = new ScheduleDAO(); private Integer selectedRow = 0; /** * Creates new form SubmissionDialog */ public SubmissionFrame() { initComponents(); table.setModel(new ResultDAO().getSubmissions()); this.setTitle(scheduleDAO.getAssessmentName() + " (" + scheduleDAO.getComplete() + "% marked)"); } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { scrollPane = new javax.swing.JScrollPane(); table = new javax.swing.JTable(); btnMark = new javax.swing.JButton(); btnQuit = new javax.swing.JButton(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setPreferredSize(new java.awt.Dimension(300, 800)); table.setModel(new javax.swing.table.DefaultTableModel( new Object [][] { {null, null}, {null, null}, {null, null}, {null, null} }, new String [] { "Submission", "Raw Mark" } ) { Class[] types = new Class [] { java.lang.String.class, java.lang.Double.class }; boolean[] canEdit = new boolean [] { false, false }; public Class getColumnClass(int columnIndex) { return types [columnIndex]; } public boolean isCellEditable(int rowIndex, int columnIndex) { return canEdit [columnIndex]; } }); table.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { tableMouseClicked(evt); } }); table.addKeyListener(new java.awt.event.KeyAdapter() { public void keyPressed(java.awt.event.KeyEvent evt) { tableKeyPressed(evt); } }); scrollPane.setViewportView(table); btnMark.setText("Mark Selected Student"); btnMark.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnMarkActionPerformed(evt); } }); btnQuit.setText("Quit"); btnQuit.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnQuitActionPerformed(evt); } }); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 376, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup() .addComponent(btnQuit) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnMark, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 251, Short.MAX_VALUE) .addGap(18, 18, 18) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(btnMark) .addComponent(btnQuit)) .addContainerGap()) ); pack(); }// </editor-fold>//GEN-END:initComponents private void btnQuitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnQuitActionPerformed System.exit(0); }//GEN-LAST:event_btnQuitActionPerformed private void btnMarkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMarkActionPerformed markSelected(); }//GEN-LAST:event_btnMarkActionPerformed private void tableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tableMouseClicked if (evt.getClickCount() >= 2) { markSelected(); } }//GEN-LAST:event_tableMouseClicked private void tableKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_tableKeyPressed if (evt.getKeyCode() == KeyEvent.VK_ENTER) { evt.consume(); markSelected(); } }//GEN-LAST:event_tableKeyPressed private void markSelected() { // get selected ID from table selectedRow = table.getSelectedRow(); String id = (String) table.getModel().getValueAt(selectedRow, 0); // copy selected ID to clipboard StringSelection stringSelection = new StringSelection(id); Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard(); clpbrd.setContents(stringSelection, null); MarkingFrame frame = new MarkingFrame(this, scheduleDAO.getAssessmentName()); // load data into frame ScheduleDAO dao = new ScheduleDAO(); for (String cat : dao.getCategories()) { frame.addCategory(cat, dao.getCriteria(cat)); } frame.load(id); frame.display(); } public void refresh(String id) { // refresh table to display new mark table.setModel(new ResultDAO().getSubmissions()); // update title to show latest completion % this.setTitle(scheduleDAO.getAssessmentName() + " (" + scheduleDAO.getComplete() + "% marked)"); // reselect the most recently selected row table.setRowSelectionInterval(selectedRow, selectedRow); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton btnMark; private javax.swing.JButton btnQuit; private javax.swing.JScrollPane scrollPane; private javax.swing.JTable table; // End of variables declaration//GEN-END:variables }
Show line notes below