Compare commits

...

4 Commits

Author SHA1 Message Date
Felix Homa bf9a7f56e0
Added Button for File-Open-Dialog 2022-03-29 13:20:59 +02:00
Felix Homa 522899eb1e
Custom Decimals Moar 2022-03-28 15:37:52 +02:00
Felix Homa b1133e0aee
Custom Decimals 2022-03-28 15:33:18 +02:00
Felix Homa d6c60bc31e
Readme added 2022-03-28 09:14:05 +02:00
9 changed files with 121 additions and 52 deletions

View File

@ -2,7 +2,8 @@
// :base gibt die Start-Punkte an und überschreibt die maximal Punkt, wenn ungleich 0 // :base gibt die Start-Punkte an und überschreibt die maximal Punkt, wenn ungleich 0
:base 0.0 :base 0.0
// Count of decimal places
:decimals 1
// Design für Punkte. Pts ist dabei für die Punkte, PtsText für den Text. die Punkte zählen als Teil des Textes (<li style=PtsText><span style=Pts>'Punkte'</span>Text</li>) // Design für Punkte. Pts ist dabei für die Punkte, PtsText für den Text. die Punkte zählen als Teil des Textes (<li style=PtsText><span style=Pts>'Punkte'</span>Text</li>)
// full -> best-Case // full -> best-Case
:fullPts color: #0f0; font-weight: bold; :fullPts color: #0f0; font-weight: bold;

11
Readme.md Normal file
View File

@ -0,0 +1,11 @@
# Korrektur Helper
für Schema-Datei Beispiel siehe Example.schema
#### Programm-Start
```
java -jar KorrekturHelper.jar <Schema-Datei>
```
Wenn `<Schema-Datei>` nicht angegeben ist, dann wird die interne Test Datei genutzt

View File

@ -16,6 +16,8 @@ public class HtmlContext
public String cbmsFail = ""; public String cbmsFail = "";
/** Style for checked Boxes in CheckboxMultiSelect */ /** Style for checked Boxes in CheckboxMultiSelect */
public String cbmsOk = ""; public String cbmsOk = "";
/** Number of Decimals on Points */
public int decimals = 1;
/** Style for the Points, when the best case Points have been achieved */ /** Style for the Points, when the best case Points have been achieved */
public String fullPtsStyle = ""; public String fullPtsStyle = "";
/** Style for the Text, when the best case Points have been achieved */ /** Style for the Text, when the best case Points have been achieved */
@ -24,6 +26,7 @@ public class HtmlContext
public MathContext mc = MathContext.DECIMAL32; public MathContext mc = MathContext.DECIMAL32;
/** Style for the Points, when the worst case Points have been achieved */ /** Style for the Points, when the worst case Points have been achieved */
public String noPtsStyle = ""; public String noPtsStyle = "";
/** Style for the Text, when the best case Points have been achieved */ /** Style for the Text, when the best case Points have been achieved */
public String noPtsTextStyle = ""; public String noPtsTextStyle = "";

View File

@ -81,7 +81,7 @@ public class KorrekturHelper
kh.frm.setVisible(true); kh.frm.setVisible(true);
} }
private static LinkedHashSet<Node> parseNodes(String[] lines, int[] lineMap) throws IOException private static LinkedHashSet<Node> parseNodes(String[] lines, int[] lineMap, HtmlContext hc) throws IOException
{ {
var roots = new LinkedHashSet<Node>(); var roots = new LinkedHashSet<Node>();
var path = new LinkedList<Node>(); var path = new LinkedList<Node>();
@ -97,10 +97,10 @@ public class KorrekturHelper
yield new HeaderNode(line.substring(path.size())); yield new HeaderNode(line.substring(path.size()));
case "[]": // [] -0.5 Punktabzug case "[]": // [] -0.5 Punktabzug
yield new CheckboxNode(line.substring(path.size())); yield new CheckboxNode(line.substring(path.size()), hc);
case "\\": // \ 1.0 Element existiert | Element existiert nicht case "\\": // \ 1.0 Element existiert | Element existiert nicht
yield new EitherNode(line.substring(path.size())); yield new EitherNode(line.substring(path.size()), hc);
case "\\\\": // \\ MultiSelects case "\\\\": // \\ MultiSelects
if (lines.length <= li) if (lines.length <= li)
@ -118,12 +118,12 @@ public class KorrekturHelper
if (lines[li + 1].trim().startsWith("[]")) if (lines[li + 1].trim().startsWith("[]"))
{ {
li = i - 1; li = i - 1;
yield new CheckboxMultiSelectNode(sb.toString()); yield new CheckboxMultiSelectNode(sb.toString(), hc);
} }
else else
{ {
li = i - 1; li = i - 1;
yield new RadioMultiSelectNode(sb.toString()); yield new RadioMultiSelectNode(sb.toString(), hc);
} }
case "": case "":
@ -200,6 +200,10 @@ public class KorrekturHelper
hc.basePoints = new BigDecimal(split[1]); hc.basePoints = new BigDecimal(split[1]);
break; break;
case ":decimals":
hc.decimals = Integer.parseInt(split[1]);
break;
case ":fullPts": case ":fullPts":
hc.fullPtsStyle = split.length > 1 ? split[1] : ""; hc.fullPtsStyle = split.length > 1 ? split[1] : "";
break; break;
@ -239,7 +243,7 @@ public class KorrekturHelper
lineMap.add(lineNumber); lineMap.add(lineNumber);
} }
} }
return parseNodes(nodeLines.toArray(String[]::new), lineMap.stream().mapToInt(i -> i).toArray()); return parseNodes(nodeLines.toArray(String[]::new), lineMap.stream().mapToInt(i -> i).toArray(), hc);
} }
private static BigDecimal recursiveAchievedPoints(LinkedHashSet<Node> nodes, MathContext mc) private static BigDecimal recursiveAchievedPoints(LinkedHashSet<Node> nodes, MathContext mc)
@ -297,14 +301,15 @@ public class KorrekturHelper
private final JButton btn_toClipboard; private final JButton btn_toClipboard;
private final JPanel contentPanel, menuPanel;
private String currentHtml = ""; private String currentHtml = "";
/** The JFrame for this {@link KorrekturHelper} */ /** The JFrame for this {@link KorrekturHelper} */
public final JFrame frm; public final JFrame frm;
private final HtmlContext hc;
private HtmlContext hc;
private boolean inReset = false; private boolean inReset = false;
private LinkedHashSet<Node> nodes;
private final LinkedHashSet<Node> nodes;
/** /**
* @param nodes Nodes * @param nodes Nodes
@ -312,16 +317,13 @@ public class KorrekturHelper
*/ */
public KorrekturHelper(LinkedHashSet<Node> nodes, HtmlContext hc) public KorrekturHelper(LinkedHashSet<Node> nodes, HtmlContext hc)
{ {
this.nodes = nodes;
this.hc = hc;
frm = new JFrame("Pinggers Korrektur Helper"); frm = new JFrame("Pinggers Korrektur Helper");
frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
var contentPanel = new JPanel(new BorderLayout(), true); contentPanel = new JPanel(new BorderLayout(), true);
/* /*
* Menu Panel * Menu Panel
*/ */
var menuPanel = new JPanel(true); menuPanel = new JPanel(true);
menuPanel.setLayout(new BoxLayout(menuPanel, BoxLayout.X_AXIS)); menuPanel.setLayout(new BoxLayout(menuPanel, BoxLayout.X_AXIS));
var jtb_aot = new JToggleButton("Always on Top"); var jtb_aot = new JToggleButton("Always on Top");
@ -335,28 +337,20 @@ public class KorrekturHelper
btn_toClipboard = new JButton("Copy to Clipboard"); btn_toClipboard = new JButton("Copy to Clipboard");
btn_toClipboard.addActionListener(e -> copyToClipboard()); btn_toClipboard.addActionListener(e -> copyToClipboard());
menuPanel.add(btn_toClipboard); menuPanel.add(btn_toClipboard);
var btn_drop = new JButton("Open Schema");
btn_drop.addActionListener(e -> fileDialog());
menuPanel.add(btn_drop);
var btn_reset = new JButton("Reset"); var btn_reset = new JButton("Reset");
btn_reset.addActionListener(e -> reset()); btn_reset.addActionListener(e -> reset());
menuPanel.add(btn_reset); menuPanel.add(btn_reset);
contentPanel.add(menuPanel, BorderLayout.NORTH); contentPanel.add(menuPanel, BorderLayout.NORTH);
setNodes(nodes, hc);
/*
* Node-Panel with Scrollpane
*/
var panel = new JPanel(true);
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
var jsp = new JScrollPane(panel);
jsp.getVerticalScrollBar().setUnitIncrement(16);
Consumer<Node> c = n -> verifyClipboard();
for (var n : nodes)
{
n.addChangeListener(c);
panel.add(n.getComponent());
}
contentPanel.add(jsp, BorderLayout.CENTER);
frm.setContentPane(contentPanel); frm.setContentPane(contentPanel);
frm.pack(); frm.pack();
if (frm.getHeight() > 900)
{
frm.setSize(frm.getWidth(), 900);
}
} }
/** /**
@ -380,6 +374,29 @@ public class KorrekturHelper
btn_toClipboard.setBackground(Color.GREEN); btn_toClipboard.setBackground(Color.GREEN);
} }
private void fileDialog()
{
var x = new JFileChooser();
if (x.showOpenDialog(frm) == JFileChooser.APPROVE_OPTION)
{
var f = x.getSelectedFile();
try (
var in = new FileInputStream(f);
var isr = new InputStreamReader(in, StandardCharsets.UTF_8);
var br = new BufferedReader(isr, 1024 * 1024)
)
{
var hc = new HtmlContext();
var n = parseSchema(br, hc);
setNodes(n, hc);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
/** /**
* Resets the Input Mask * Resets the Input Mask
*/ */
@ -391,6 +408,34 @@ public class KorrekturHelper
verifyClipboard(); verifyClipboard();
} }
/**
* Set the Nodes and {@link HtmlContext}
*
* @param nodes nodes
* @param hc context
*/
public void setNodes(LinkedHashSet<Node> nodes, HtmlContext hc)
{
this.nodes = nodes;
this.hc = hc;
/*
* Node-Panel with Scrollpane
*/
var panel = new JPanel(true);
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
var jsp = new JScrollPane(panel);
jsp.getVerticalScrollBar().setUnitIncrement(16);
Consumer<Node> c = n -> verifyClipboard();
for (var n : nodes)
{
n.addChangeListener(c);
panel.add(n.getComponent());
}
contentPanel.removeAll();
contentPanel.add(menuPanel, BorderLayout.NORTH);
contentPanel.add(jsp, BorderLayout.CENTER);
}
/** /**
* Called on change of data or when the System signifies, the Clipboard changed * Called on change of data or when the System signifies, the Clipboard changed
*/ */

View File

@ -11,12 +11,13 @@ public class Utils
/** /**
* formats Points for Users * formats Points for Users
* *
* @param bd the {@link BigDecimal} to format * @param bd the {@link BigDecimal} to format
* @param decimals decimals
* @return the formatted String (1 decimal place) * @return the formatted String (1 decimal place)
*/ */
public static String formatPoints(BigDecimal bd) public static String formatPoints(BigDecimal bd, int decimals)
{ {
return String.format("%.1f", bd.doubleValue()); return String.format("%." + decimals + "f", bd.doubleValue());
} }
/** /**

View File

@ -25,8 +25,9 @@ public class CheckboxMultiSelectNode extends AbstractNode
/** /**
* @param config the config string to parse * @param config the config string to parse
* @param hc {@link HtmlContext}
*/ */
public CheckboxMultiSelectNode(String config) public CheckboxMultiSelectNode(String config, HtmlContext hc)
{ {
var lines = config.split("\n"); var lines = config.split("\n");
if (lines.length <= 1) if (lines.length <= 1)
@ -58,7 +59,7 @@ public class CheckboxMultiSelectNode extends AbstractNode
{ throw new IllegalArgumentException("Expected []"); } { throw new IllegalArgumentException("Expected []"); }
points[i - 1] = new BigDecimal(s[1]); points[i - 1] = new BigDecimal(s[1]);
text[i - 1] = s[2]; text[i - 1] = s[2];
rbs[i - 1] = new JCheckBox(Utils.formatPoints(points[i - 1]) + "P - " + text[i - 1]); rbs[i - 1] = new JCheckBox(Utils.formatPoints(points[i - 1], hc.decimals) + "P - " + text[i - 1]);
rbs[i - 1].addActionListener(cl); rbs[i - 1].addActionListener(cl);
content.add(rbs[i - 1]); content.add(rbs[i - 1]);
} }
@ -124,7 +125,8 @@ public class CheckboxMultiSelectNode extends AbstractNode
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.append("<li").append(hc.styleText(achievedPoints(hc.mc), maxPoints)).append(">"); sb.append("<li").append(hc.styleText(achievedPoints(hc.mc), maxPoints)).append(">");
sb.append("<span").append(hc.stylePts(achievedPoints(hc.mc), maxPoints)).append(">"); sb.append("<span").append(hc.stylePts(achievedPoints(hc.mc), maxPoints)).append(">");
sb.append(Utils.formatPoints(achievedPoints(hc.mc))).append(" / ").append(Utils.formatPoints(maxPoints)); sb.append(Utils.formatPoints(achievedPoints(hc.mc), hc.decimals)).append(" / ")
.append(Utils.formatPoints(maxPoints, hc.decimals));
sb.append("P</span> "); sb.append("P</span> ");
sb.append(baseMsg); sb.append(baseMsg);
sb.append("\n\t<ul style=\"list-style-type: none;margin-top: 0px;margin-bottom:0px\">\n"); sb.append("\n\t<ul style=\"list-style-type: none;margin-top: 0px;margin-bottom:0px\">\n");
@ -132,7 +134,7 @@ public class CheckboxMultiSelectNode extends AbstractNode
{ {
sb.append("\t\t<li").append(hc.cbx(rbs[i])).append(">"); sb.append("\t\t<li").append(hc.cbx(rbs[i])).append(">");
sb.append(rbs[i].isSelected() ? "&checkmark; " : "&cross; "); sb.append(rbs[i].isSelected() ? "&checkmark; " : "&cross; ");
sb.append("(").append(Utils.formatPoints(points[i])).append("P) "); sb.append("(").append(Utils.formatPoints(points[i], hc.decimals)).append("P) ");
sb.append(text[i]); sb.append(text[i]);
sb.append("</li>\n"); sb.append("</li>\n");
} }

View File

@ -21,8 +21,9 @@ public class CheckboxNode extends AbstractNode
/** /**
* @param configString config String to parse * @param configString config String to parse
* @param hc {@link HtmlContext}
*/ */
public CheckboxNode(String configString) public CheckboxNode(String configString, HtmlContext hc)
{ {
if (configString.contains("\n")) if (configString.contains("\n"))
{ throw new IllegalArgumentException("Bad config! Found line feed!"); } { throw new IllegalArgumentException("Bad config! Found line feed!"); }
@ -33,7 +34,7 @@ public class CheckboxNode extends AbstractNode
{ throw new IllegalArgumentException("Not a [] Node"); } { throw new IllegalArgumentException("Not a [] Node"); }
points = new BigDecimal(spl[1]); points = new BigDecimal(spl[1]);
message = spl[2]; message = spl[2];
cbx = new JCheckBox(Utils.formatPoints(points) + "P " + message); cbx = new JCheckBox(Utils.formatPoints(points, hc.decimals) + "P " + message);
cbx.addActionListener(e -> onChange(this)); cbx.addActionListener(e -> onChange(this));
content.add(cbx); content.add(cbx);
} }
@ -70,7 +71,7 @@ public class CheckboxNode extends AbstractNode
public String toResultHtml(HtmlContext hc) public String toResultHtml(HtmlContext hc)
{ {
return "<li" + hc.styleText(points.signum()) + "><span" + hc.stylePts(points.signum()) + ">" return "<li" + hc.styleText(points.signum()) + "><span" + hc.stylePts(points.signum()) + ">"
+ Utils.formatPoints(achievedPoints(hc.mc)) + "P</span> " + message + "</li>"; + Utils.formatPoints(achievedPoints(hc.mc), hc.decimals) + "P</span> " + message + "</li>";
} }
} }

View File

@ -25,8 +25,9 @@ public class EitherNode extends AbstractNode
/** /**
* @param config the config String * @param config the config String
* @param hc {@link HtmlContext}
*/ */
public EitherNode(String config) public EitherNode(String config, HtmlContext hc)
{ {
if (config.contains("\n")) if (config.contains("\n"))
{ throw new IllegalArgumentException("Bad config! Found line feed!"); } { throw new IllegalArgumentException("Bad config! Found line feed!"); }
@ -42,14 +43,15 @@ public class EitherNode extends AbstractNode
messageFail = spl.length == 3 ? null : spl.length == 4 ? spl[3].substring(1).trim() : spl[4]; messageFail = spl.length == 3 ? null : spl.length == 4 ? spl[3].substring(1).trim() : spl[4];
if (points.signum() > 0) if (points.signum() > 0)
{ {
btn_ok = new JRadioButton(Utils.formatPoints(points) + "P " + messageOK); btn_ok = new JRadioButton(Utils.formatPoints(points, hc.decimals) + "P " + messageOK);
btn_fail = new JRadioButton( btn_fail = new JRadioButton(
Utils.ptsToString(BigDecimal.ZERO) + "P " + (messageFail == null ? messageOK : messageFail)); Utils.formatPoints(BigDecimal.ZERO, hc.decimals) + "P " + (messageFail == null ? messageOK : messageFail));
} }
else else
{ {
btn_ok = new JRadioButton(Utils.formatPoints(BigDecimal.ZERO) + "P " + messageOK); btn_ok = new JRadioButton(Utils.formatPoints(BigDecimal.ZERO, hc.decimals) + "P " + messageOK);
btn_fail = new JRadioButton(Utils.formatPoints(points) + "P " + (messageFail == null ? messageOK : messageFail)); btn_fail = new JRadioButton(
Utils.formatPoints(points, hc.decimals) + "P " + (messageFail == null ? messageOK : messageFail));
} }
btn_ok.addActionListener(e -> onChange(this)); btn_ok.addActionListener(e -> onChange(this));
btn_fail.addActionListener(e -> onChange(this)); btn_fail.addActionListener(e -> onChange(this));
@ -127,8 +129,8 @@ public class EitherNode extends AbstractNode
} }
return "<li" + hc.styleText(signum) + ">" + // return "<li" + hc.styleText(signum) + ">" + //
"<span" + hc.stylePts(signum) + ">" + // "<span" + hc.stylePts(signum) + ">" + //
Utils.formatPoints(achievedPoints(hc.mc)) + // Utils.formatPoints(achievedPoints(hc.mc), hc.decimals) + //
(points.signum() < 0 ? "" : " / " + Utils.formatPoints(maximumPoints())) + "P" + // (points.signum() < 0 ? "" : " / " + Utils.formatPoints(maximumPoints(), hc.decimals)) + "P" + //
"</span> " + // "</span> " + //
(points.signum() < 0 ? btn_fail.isSelected() ? messageOK : messageFail (points.signum() < 0 ? btn_fail.isSelected() ? messageOK : messageFail
: btn_fail.isSelected() ? messageFail : messageOK) : btn_fail.isSelected() ? messageFail : messageOK)

View File

@ -28,8 +28,9 @@ public class RadioMultiSelectNode extends AbstractNode
/** /**
* @param config the config string to parse * @param config the config string to parse
* @param hc htmlContext
*/ */
public RadioMultiSelectNode(String config) public RadioMultiSelectNode(String config, HtmlContext hc)
{ {
var lines = config.split("\n"); var lines = config.split("\n");
if (lines.length <= 1) if (lines.length <= 1)
@ -60,7 +61,7 @@ public class RadioMultiSelectNode extends AbstractNode
{ throw new IllegalArgumentException("Expected exactly 1 \\t"); } { throw new IllegalArgumentException("Expected exactly 1 \\t"); }
points[i - 1] = new BigDecimal(s[0]); points[i - 1] = new BigDecimal(s[0]);
text[i - 1] = s[1]; text[i - 1] = s[1];
rbs[i - 1] = new JRadioButton(Utils.formatPoints(points[i - 1]) + "P - " + text[i - 1]); rbs[i - 1] = new JRadioButton(Utils.formatPoints(points[i - 1], hc.decimals) + "P - " + text[i - 1]);
rbs[i - 1].addActionListener(cl); rbs[i - 1].addActionListener(cl);
content.add(rbs[i - 1]); content.add(rbs[i - 1]);
bg.add(rbs[i - 1]); bg.add(rbs[i - 1]);
@ -131,12 +132,14 @@ public class RadioMultiSelectNode extends AbstractNode
{ {
return "<li" + hc.styleText(BigDecimal.ZERO, maxPoints) + ">" + // return "<li" + hc.styleText(BigDecimal.ZERO, maxPoints) + ">" + //
"<span" + hc.stylePts(achievedPoints(hc.mc), maxPoints) + ">" + // "<span" + hc.stylePts(achievedPoints(hc.mc), maxPoints) + ">" + //
Utils.formatPoints(BigDecimal.ZERO) + " / " + Utils.formatPoints(maxPoints) + "P</span> " + // Utils.formatPoints(BigDecimal.ZERO, hc.decimals) + " / " + Utils.formatPoints(maxPoints, hc.decimals)
+ "P</span> " + //
(baseMsg == null ? "" : baseMsg) + "</li>"; (baseMsg == null ? "" : baseMsg) + "</li>";
} }
return "<li" + hc.styleText(achievedPoints(hc.mc), maxPoints) + ">" + // return "<li" + hc.styleText(achievedPoints(hc.mc), maxPoints) + ">" + //
"<span" + hc.stylePts(achievedPoints(hc.mc), maxPoints) + "> " + // "<span" + hc.stylePts(achievedPoints(hc.mc), maxPoints) + "> " + //
Utils.formatPoints(achievedPoints(hc.mc)) + " / " + Utils.formatPoints(maxPoints) + "P</span> " + // Utils.formatPoints(achievedPoints(hc.mc), hc.decimals) + " / " + Utils.formatPoints(maxPoints, hc.decimals)
+ "P</span> " + //
(baseMsg == null ? text[getSelected()] : baseMsg + " (" + text[getSelected()] + ")") + "</li>"; (baseMsg == null ? text[getSelected()] : baseMsg + " (" + text[getSelected()] + ")") + "</li>";
} }