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
Add textarea font size property since the default is tiny on 4K screens.
master
1 parent
da6ab4a
commit
d8d343caacdf6ecb6482e24747486d861053093b
Mark George
authored
on 7 Apr 2024
Patch
Showing
3 changed files
src/main/java/dao/MarkingProperties.java
src/main/java/ui/CriterionPanel.java
src/main/resources/marking.properties
Ignore Space
Show notes
View
src/main/java/dao/MarkingProperties.java
package dao; import java.io.FileInputStream; import java.io.IOException; import java.util.Properties; import javax.swing.JOptionPane; /** * * @author Mark George <mark.george@otago.ac.nz> */ @SuppressWarnings("StaticNonFinalUsedInInitialization") public class MarkingProperties { private static Properties properties = null; static { if (properties == null) { properties = new Properties(); try { // production properties.load(new FileInputStream("marking.properties")); } catch (IOException ex1) { try { // development properties.load(MarkingProperties.class.getResourceAsStream("/marking.properties")); } catch (IOException ex2) { JOptionPane.showMessageDialog(null, "marking.properties not found!"); } } } } public static String jdbcUri() { return properties.getProperty("jdbc.url").trim(); } public static String reportPath() { return properties.getProperty("report.dir").trim(); } public static String attachmentEmailName() { return properties.getProperty("attachment.email.name").trim(); } public static String attachmentFilePrefix() { return properties.getProperty("attachment.file.prefix").trim(); } public static String assessmentDescription() { return properties.getProperty("assessment.description").trim(); } public static Boolean isEmailEnabled() { return properties.getProperty("enable.email").trim().equalsIgnoreCase("true"); } public static String smtpHost() { return properties.getProperty("smtp.host").trim(); } public static Boolean isTls() { return properties.getProperty("smtp.tls").trim().equalsIgnoreCase("true"); } public static String smtpUserName() { return properties.getProperty("smtp.user.name").trim(); } public static String markerName() { return properties.getProperty("marker.name").trim(); } public static String markerEmail() { return properties.getProperty("marker.email").trim(); } public static String ccEmail() { return properties.getProperty("cc.email").trim(); } public static Integer smtpPort() { return Integer.valueOf(properties.getProperty("smtp.port").trim()); } public static Integer emailDelay() { return Integer.valueOf(properties.getProperty("email.delay").trim()); } public static Boolean reportShowMax() { return properties.getProperty("report.showmax").trim().equalsIgnoreCase("true"); } public static String reportTitle() { return properties.getProperty("report.title").trim(); } public static String reportFooter() { return properties.getProperty("report.footer").trim(); } public static String paperCode() { return properties.getProperty("paper.code").trim(); } public static Integer textAreaFontSize() { return Integer.valueOf(properties.getProperty("textarea.fontsize").trim()); } }
package dao; import java.io.FileInputStream; import java.io.IOException; import java.util.Properties; import javax.swing.JOptionPane; /** * * @author Mark George <mark.george@otago.ac.nz> */ @SuppressWarnings("StaticNonFinalUsedInInitialization") public class MarkingProperties { private static Properties properties = null; static { if (properties == null) { properties = new Properties(); try { // production properties.load(new FileInputStream("marking.properties")); } catch (IOException ex1) { try { // development properties.load(MarkingProperties.class.getResourceAsStream("/marking.properties")); } catch (IOException ex2) { JOptionPane.showMessageDialog(null, "marking.properties not found!"); } } } } public static String jdbcUri() { return properties.getProperty("jdbc.url").trim(); } public static String reportPath() { return properties.getProperty("report.dir").trim(); } public static String attachmentEmailName() { return properties.getProperty("attachment.email.name").trim(); } public static String attachmentFilePrefix() { return properties.getProperty("attachment.file.prefix").trim(); } public static String assessmentDescription() { return properties.getProperty("assessment.description").trim(); } public static Boolean isEmailEnabled() { return properties.getProperty("enable.email").trim().equalsIgnoreCase("true"); } public static String smtpHost() { return properties.getProperty("smtp.host").trim(); } public static Boolean isTls() { return properties.getProperty("smtp.tls").trim().equalsIgnoreCase("true"); } public static String smtpUserName() { return properties.getProperty("smtp.user.name").trim(); } public static String markerName() { return properties.getProperty("marker.name").trim(); } public static String markerEmail() { return properties.getProperty("marker.email").trim(); } public static String ccEmail() { return properties.getProperty("cc.email").trim(); } public static Integer smtpPort() { return Integer.valueOf(properties.getProperty("smtp.port").trim()); } public static Integer emailDelay() { return Integer.valueOf(properties.getProperty("email.delay").trim()); } public static Boolean reportShowMax() { return properties.getProperty("report.showmax").trim().equalsIgnoreCase("true"); } public static String reportTitle() { return properties.getProperty("report.title").trim(); } public static String reportFooter() { return properties.getProperty("report.footer").trim(); } public static String paperCode() { return properties.getProperty("paper.code").trim(); } }
Ignore Space
Show notes
View
src/main/java/ui/CriterionPanel.java
package ui; import dao.MarkingProperties; import java.awt.Dimension; import java.awt.Font; import model.CriterionEditor; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.SwingUtilities; import model.Criterion; /** * * @author Mark George <mark.george@otago.ac.nz> */ public class CriterionPanel extends JPanel implements CriterionEditor { private RadioGroup radioGroup = null; private final JTextArea txtComment; private final Criterion criterion; private final JButton clearBtn; private JTextField txtNumeric = null; private static Dimension selectedSize; @SuppressWarnings("Convert2Lambda") public CriterionPanel(Criterion criterion) { this.criterion = criterion; this.setLayout(new GridBagLayout()); // label is left aligned and full width GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.gridwidth = 3; gbc.weightx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.insets = new Insets(0, 0, 5, 0); this.add(new JLabel(criterion.getDescription()), gbc); // clear mark buttonleft aligned, but doesn't grow gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 1; clearBtn = new JButton("X"); this.add(clearBtn, gbc); // mark component is left aligned, but doesn't grow gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 1; if (criterion.isScale()) { radioGroup = new RadioGroup(criterion.getMin(), criterion.getMax()); this.add(radioGroup, gbc); } else { gbc.insets.left = 20; gbc.insets.right = 20; gbc.fill = GridBagConstraints.HORIZONTAL; txtNumeric = new JTextField(); txtNumeric.setToolTipText("Out of " + criterion.getMax()); this.add(txtNumeric, gbc); } // text area is right aligned, but grows in both directions gbc = new GridBagConstraints(); gbc.gridx = 2; gbc.gridy = 1; gbc.weightx = 1; gbc.weighty = 1; gbc.fill = GridBagConstraints.BOTH; txtComment = new JTextArea(); txtComment.setWrapStyleWord(true); txtComment.setLineWrap(true); JScrollPane scrollPane = new JScrollPane(); scrollPane.setViewportView(txtComment); scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); // Dimensions are necessary to prevent the semi-famous "text area grows infinitely" bug. // Unfortunately this also means we can't let the layout manager figure out the correct // size dynamically... txtComment.setMinimumSize(new Dimension(10, 20)); txtComment.setPreferredSize(new Dimension(10, 100)); // need to hardcode height which is annoying... scrollPane.setPreferredSize(new Dimension(10, 20)); txtComment.addFocusListener(new FocusAdapter() { @Override public void focusGained(FocusEvent fe) { super.focusGained(fe); CriterionPanel selectedPanel = CriterionPanel.this; MarkingFrame frame = (MarkingFrame) SwingUtilities.getWindowAncestor(selectedPanel); if (frame.getExpandable()) { selectedPanel.setPreferredSize(new Dimension(10, 150)); selectedPanel.invalidate(); SwingUtilities.getWindowAncestor(selectedPanel).pack(); } } @Override public void focusLost(FocusEvent fe) { super.focusLost(fe); CriterionPanel selectedPanel = CriterionPanel.this; MarkingFrame frame = (MarkingFrame) SwingUtilities.getWindowAncestor(selectedPanel); if (frame.getExpandable()) { selectedPanel.setPreferredSize(selectedSize); selectedPanel.invalidate(); SwingUtilities.getWindowAncestor(selectedPanel).pack(); } } }); clearBtn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { if (criterion.isScale()) { radioGroup.clearSelection(); } else { txtNumeric.setText(""); } } }); Font font = txtComment.getFont(); Font biggerFont = font.deriveFont(MarkingProperties.textAreaFontSize()); txtComment.setFont(biggerFont); this.add(scrollPane, gbc); } @Override public String getComment() { return txtComment.getText().trim(); } @Override // TODO: switch to BigDeciamal public Double getResult() { if (criterion.isScale()) { Integer result = radioGroup.getSelected(); return result != null ? Double.valueOf(result) : null; } else { try { String val = txtNumeric.getText(); if (val.isBlank()) { // mark not entered, so return null return null; } Double result = Double.valueOf(val); if (result < criterion.getMin() || result > criterion.getMax()) { JOptionPane.showMessageDialog(null, txtNumeric.getText() + " is not within the exected range.\n\nMinimum: " + criterion.getMin() + "\nMaximum: " + criterion.getMax(), "Invalid Number", JOptionPane.ERROR_MESSAGE); throw new RuntimeException("Number is not within expected range"); } return Double.valueOf(txtNumeric.getText()); } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(null, txtNumeric.getText() + " is not a valid number", "Invalid Number", JOptionPane.ERROR_MESSAGE); throw new RuntimeException(ex.getLocalizedMessage()); } } } @Override public boolean isComplete() { return getResult() != null; } @Override public void setComment(String comment) { txtComment.setText(comment); } @Override public void setResult(Double result) { if (criterion.isScale()) { radioGroup.setSelected(result.intValue()); } else { txtNumeric.setText(String.valueOf(result)); } } public void setZero() { setResult(0.0); } public void setMax() { setResult(Double.valueOf(criterion.getMax())); } public Criterion getCriterion() { return criterion; } }
package ui; import java.awt.Dimension; import java.awt.Font; import model.CriterionEditor; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.SwingUtilities; import model.Criterion; /** * * @author Mark George <mark.george@otago.ac.nz> */ public class CriterionPanel extends JPanel implements CriterionEditor { private RadioGroup radioGroup = null; private final JTextArea txtComment; private final Criterion criterion; private final JButton clearBtn; private JTextField txtNumeric = null; private static Dimension selectedSize; @SuppressWarnings("Convert2Lambda") public CriterionPanel(Criterion criterion) { this.criterion = criterion; this.setLayout(new GridBagLayout()); // label is left aligned and full width GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.gridwidth = 3; gbc.weightx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.insets = new Insets(0, 0, 5, 0); this.add(new JLabel(criterion.getDescription()), gbc); // clear mark buttonleft aligned, but doesn't grow gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 1; clearBtn = new JButton("X"); this.add(clearBtn, gbc); // mark component is left aligned, but doesn't grow gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 1; if (criterion.isScale()) { radioGroup = new RadioGroup(criterion.getMin(), criterion.getMax()); this.add(radioGroup, gbc); } else { gbc.insets.left = 20; gbc.insets.right = 20; gbc.fill = GridBagConstraints.HORIZONTAL; txtNumeric = new JTextField(); txtNumeric.setToolTipText("Out of " + criterion.getMax()); this.add(txtNumeric, gbc); } // text area is right aligned, but grows in both directions gbc = new GridBagConstraints(); gbc.gridx = 2; gbc.gridy = 1; gbc.weightx = 1; gbc.weighty = 1; gbc.fill = GridBagConstraints.BOTH; txtComment = new JTextArea(); txtComment.setWrapStyleWord(true); txtComment.setLineWrap(true); JScrollPane scrollPane = new JScrollPane(); scrollPane.setViewportView(txtComment); scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); // Dimensions are necessary to prevent the semi-famous "text area grows infinitely" bug. // Unfortunately this also means we can't let the layout manager figure out the correct // size dynamically... txtComment.setMinimumSize(new Dimension(10, 20)); txtComment.setPreferredSize(new Dimension(10, 100)); // need to hardcode height which is annoying... scrollPane.setPreferredSize(new Dimension(10, 20)); txtComment.addFocusListener(new FocusAdapter() { @Override public void focusGained(FocusEvent fe) { super.focusGained(fe); CriterionPanel selectedPanel = CriterionPanel.this; MarkingFrame frame = (MarkingFrame) SwingUtilities.getWindowAncestor(selectedPanel); if (frame.getExpandable()) { selectedPanel.setPreferredSize(new Dimension(10, 150)); selectedPanel.invalidate(); SwingUtilities.getWindowAncestor(selectedPanel).pack(); } } @Override public void focusLost(FocusEvent fe) { super.focusLost(fe); CriterionPanel selectedPanel = CriterionPanel.this; MarkingFrame frame = (MarkingFrame) SwingUtilities.getWindowAncestor(selectedPanel); if (frame.getExpandable()) { selectedPanel.setPreferredSize(selectedSize); selectedPanel.invalidate(); SwingUtilities.getWindowAncestor(selectedPanel).pack(); } } }); clearBtn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { if (criterion.isScale()) { radioGroup.clearSelection(); } else { txtNumeric.setText(""); } } }); Font font = txtComment.getFont(); Font biggerFont = font.deriveFont(14f); txtComment.setFont(biggerFont); this.add(scrollPane, gbc); } @Override public String getComment() { return txtComment.getText().trim(); } @Override // TODO: switch to BigDeciamal public Double getResult() { if (criterion.isScale()) { Integer result = radioGroup.getSelected(); return result != null ? Double.valueOf(result) : null; } else { try { String val = txtNumeric.getText(); if (val.isBlank()) { // mark not entered, so return null return null; } Double result = Double.valueOf(val); if (result < criterion.getMin() || result > criterion.getMax()) { JOptionPane.showMessageDialog(null, txtNumeric.getText() + " is not within the exected range.\n\nMinimum: " + criterion.getMin() + "\nMaximum: " + criterion.getMax(), "Invalid Number", JOptionPane.ERROR_MESSAGE); throw new RuntimeException("Number is not within expected range"); } return Double.valueOf(txtNumeric.getText()); } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(null, txtNumeric.getText() + " is not a valid number", "Invalid Number", JOptionPane.ERROR_MESSAGE); throw new RuntimeException(ex.getLocalizedMessage()); } } } @Override public boolean isComplete() { return getResult() != null; } @Override public void setComment(String comment) { txtComment.setText(comment); } @Override public void setResult(Double result) { if (criterion.isScale()) { radioGroup.setSelected(result.intValue()); } else { txtNumeric.setText(String.valueOf(result)); } } public void setZero() { setResult(0.0); } public void setMax() { setResult(Double.valueOf(criterion.getMax())); } public Criterion getCriterion() { return criterion; } }
Ignore Space
Show notes
View
src/main/resources/marking.properties
jdbc.url=jdbc:h2:./db/testing;IFEXISTS=TRUE;AUTO_SERVER=TRUE # output dir for generated reports report.dir=/tmp/reports # local testing smtp.host=localhost smtp.port=2525 smtp.user.name=n/a smtp.tls=false # real server #smtp.host=smtp.staff.otago.ac.nz #smtp.port=587 #smtp.user.name=geoma48p #smtp.tls=true marker.name=Mark George marker.email=mark.george@otago.ac.nz cc.email=cc@example.com attachment.email.name=testing.pdf attachment.file.prefix=milestone2 assessment.description=Milestone 2 # does email button appear in UI enable.email=true # email delay in seconds (rate limiting) email.delay=5 # show maximum on report report.showmax=true report.title=INFO202: Developing Information Systems 2\nAssessment Feedback report.footer=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. paper.code=INFO202 textarea.fontsize = 12
jdbc.url=jdbc:h2:./db/testing;IFEXISTS=TRUE;AUTO_SERVER=TRUE # output dir for generated reports report.dir=/tmp/reports # local testing smtp.host=localhost smtp.port=2525 smtp.user.name=n/a smtp.tls=false # real server #smtp.host=smtp.staff.otago.ac.nz #smtp.port=587 #smtp.user.name=geoma48p #smtp.tls=true marker.name=Mark George marker.email=mark.george@otago.ac.nz cc.email=cc@example.com attachment.email.name=testing.pdf attachment.file.prefix=milestone2 assessment.description=Milestone 2 # does email button appear in UI enable.email=true # email delay in seconds (rate limiting) email.delay=5 # show maximum on report report.showmax=true report.title=INFO202: Developing Information Systems 2\nAssessment Feedback report.footer=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. paper.code=INFO202
Show line notes below