RadioMultiSelect

This commit is contained in:
Felix Homa 2022-03-28 00:02:15 +02:00
parent 75dcb2c2d4
commit 593e489b3a
Signed by: felix.homa
GPG Key ID: 43610F311720D3DA
5 changed files with 280 additions and 7 deletions

View File

@ -0,0 +1,123 @@
package de.tuDortmund.cs.rvs.pingger.korrekturHelper;
import java.math.BigDecimal;
import java.math.MathContext;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
/**
* @author Pingger
*/
public class CheckboxMultiSelect extends AbstractNode
{
private final String baseMsg;
private final ButtonGroup bg;
private final BigDecimal maxPoints;
private final BigDecimal[] points;
private final JCheckBox[] rbs;
private final String[] text;
/**
* @param config the config string to parse
*/
public CheckboxMultiSelect(String config)
{
var lines = config.split("\n");
var spl0 = lines[0].split("\t");
if (!"\\\\".equals(spl0[0]))
{ throw new IllegalArgumentException("Expected \\\\"); }
if (spl0.length != 2 && spl0.length != 3)
{ throw new IllegalArgumentException("Expected 1 or 2 \\t"); }
maxPoints = new BigDecimal(spl0[1]);
if (maxPoints.signum() <= 0)
{ throw new IllegalArgumentException("Positive Points required! got: " + maxPoints); }
baseMsg = spl0.length == 3 ? spl0[2] : null;
points = new BigDecimal[lines.length - 1];
text = new String[lines.length - 1];
rbs = new JCheckBox[lines.length - 1];
bg = new ButtonGroup();
content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
if (baseMsg != null)
{
content.add(new JLabel(baseMsg));
}
for (var i = 1; i < lines.length; i++)
{
var s = lines[i].split("\t");
if (s.length != 2)
{ throw new IllegalArgumentException("Expected exactly 1 \\t"); }
points[i - 1] = new BigDecimal(s[0]);
text[i - 1] = s[1];
rbs[i - 1] = new JCheckBox(text[i - 1]);
content.add(rbs[i - 1]);
bg.add(rbs[i - 1]);
}
}
@Override
protected void _reset()
{
bg.clearSelection();
}
@Override
public BigDecimal achievedPoints(MathContext mc)
{
return points[getSelected()];
}
private int getSelected()
{
for (var i = 0; i < rbs.length; i++)
{
if (rbs[i].isSelected())
{ return i; }
}
return rbs.length - 1;
}
@Override
public boolean isVisibleInResultHtml()
{ return true; }
@Override
public BigDecimal maximumPoints()
{
return maxPoints;
}
@Override
public String toConfigString()
{
var sb = new StringBuilder();
sb.append("\\\\\t");
sb.append(maxPoints.toPlainString());
if (baseMsg != null)
{
sb.append("\t");
sb.append(baseMsg);
}
for (var i = 0; i < text.length; i++)
{
sb.append("\n\t");
sb.append(points[i].toPlainString());
sb.append("\t");
sb.append(text[i]);
}
return sb.toString();
}
@Override
public String toResultHtml(HtmlContext hc)
{
return "<li" + hc.styleText(achievedPoints(hc.mc), maxPoints) + ">" + //
"<span" + hc.stylePts(achievedPoints(hc.mc), maxPoints) + ">" + //
achievedPoints(hc.mc) + "/" + maxPoints.toPlainString() + "P</span>" + //
(baseMsg == null ? text[getSelected()] : baseMsg + " (" + text[getSelected()] + ")") + "</li>";
}
}

View File

@ -28,11 +28,11 @@ public class EitherNode extends AbstractNode
if (config.contains("\n")) if (config.contains("\n"))
{ throw new IllegalArgumentException("Bad config! Found line feed!"); } { throw new IllegalArgumentException("Bad config! Found line feed!"); }
var spl = config.split("\t"); var spl = config.split("\t");
if (spl.length != 4 && spl.length != 5) if (spl.length < 3 || spl.length > 5)
{ throw new IllegalArgumentException("Expected 2, 3 or 4 \\t!"); } { throw new IllegalArgumentException("Expected 2, 3 or 4 \\t!"); }
if (!"\\".equals(spl[0])) if (!"\\".equals(spl[0]))
{ throw new IllegalArgumentException("Expected \\"); } { throw new IllegalArgumentException("Expected \\"); }
if (!"|".equals(spl[3])) if (spl.length > 3 && !"|".equals(spl[3]))
{ throw new IllegalArgumentException("Expected | after 3rd \\t"); } { throw new IllegalArgumentException("Expected | after 3rd \\t"); }
this.points = new BigDecimal(spl[1]); this.points = new BigDecimal(spl[1]);
messageOK = spl[2]; messageOK = spl[2];

View File

@ -1,5 +1,6 @@
package de.tuDortmund.cs.rvs.pingger.korrekturHelper; package de.tuDortmund.cs.rvs.pingger.korrekturHelper;
import java.math.BigDecimal;
import java.math.MathContext; import java.math.MathContext;
/** /**
@ -29,6 +30,21 @@ public class HtmlContext
*/ */
public String partialPtsTextStyle = ""; public String partialPtsTextStyle = "";
/**
* @param got achieved Points
* @param max maximum Points
* @return the style tag-parameter for the given signum for the Points
* @implNote Does not support negative points!
*/
public String stylePts(BigDecimal got, BigDecimal max)
{
if (got.equals(BigDecimal.ZERO))
{ return noPtsStyle.isBlank() ? "" : " style=\"" + noPtsStyle + "\""; }
if (got.compareTo(max) < 0)
{ return partialPtsStyle.isBlank() ? "" : " style=\"" + partialPtsStyle + "\""; }
return fullPtsStyle.isBlank() ? "" : " style=\"" + fullPtsStyle + "\"";
}
/** /**
* @param signum the style-signum -1 worst case, 0 partial case, 1 best case * @param signum the style-signum -1 worst case, 0 partial case, 1 best case
* @return the style tag-parameter for the given signum for the Points * @return the style tag-parameter for the given signum for the Points
@ -44,6 +60,21 @@ public class HtmlContext
}; };
} }
/**
* @param got achieved Points
* @param max maximum Points
* @return the style tag-parameter for the given signum for the Points
* @implNote Does not support negative points!
*/
public String styleText(BigDecimal got, BigDecimal max)
{
if (got.equals(BigDecimal.ZERO))
{ return noPtsTextStyle.isBlank() ? "" : " style=\"" + noPtsTextStyle + "\""; }
if (got.compareTo(max) < 0)
{ return partialPtsTextStyle.isBlank() ? "" : " style=\"" + partialPtsTextStyle + "\""; }
return fullPtsTextStyle.isBlank() ? "" : " style=\"" + fullPtsTextStyle + "\"";
}
/** /**
* @param signum the style-signum -1 worst case, 0 partial case, 1 best case * @param signum the style-signum -1 worst case, 0 partial case, 1 best case
* @return the style tag-parameter for the given signum for the Text * @return the style tag-parameter for the given signum for the Text

View File

@ -0,0 +1,123 @@
package de.tuDortmund.cs.rvs.pingger.korrekturHelper;
import java.math.BigDecimal;
import java.math.MathContext;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JLabel;
import javax.swing.JRadioButton;
/**
* @author Pingger
*/
public class RadioMultiSelect extends AbstractNode
{
private final String baseMsg;
private final ButtonGroup bg;
private final BigDecimal maxPoints;
private final BigDecimal[] points;
private final JRadioButton[] rbs;
private final String[] text;
/**
* @param config the config string to parse
*/
public RadioMultiSelect(String config)
{
var lines = config.split("\n");
var spl0 = lines[0].split("\t");
if (!"\\\\".equals(spl0[0]))
{ throw new IllegalArgumentException("Expected \\\\"); }
if (spl0.length != 2 && spl0.length != 3)
{ throw new IllegalArgumentException("Expected 1 or 2 \\t"); }
maxPoints = new BigDecimal(spl0[1]);
if (maxPoints.signum() <= 0)
{ throw new IllegalArgumentException("Positive Points required! got: " + maxPoints); }
baseMsg = spl0.length == 3 ? spl0[2] : null;
points = new BigDecimal[lines.length - 1];
text = new String[lines.length - 1];
rbs = new JRadioButton[lines.length - 1];
bg = new ButtonGroup();
content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
if (baseMsg != null)
{
content.add(new JLabel(baseMsg));
}
for (var i = 1; i < lines.length; i++)
{
var s = lines[i].split("\t");
if (s.length != 2)
{ throw new IllegalArgumentException("Expected exactly 1 \\t"); }
points[i - 1] = new BigDecimal(s[0]);
text[i - 1] = s[1];
rbs[i - 1] = new JRadioButton(text[i - 1]);
content.add(rbs[i - 1]);
bg.add(rbs[i - 1]);
}
}
@Override
protected void _reset()
{
bg.clearSelection();
}
@Override
public BigDecimal achievedPoints(MathContext mc)
{
return points[getSelected()];
}
private int getSelected()
{
for (var i = 0; i < rbs.length; i++)
{
if (rbs[i].isSelected())
{ return i; }
}
return rbs.length - 1;
}
@Override
public boolean isVisibleInResultHtml()
{ return true; }
@Override
public BigDecimal maximumPoints()
{
return maxPoints;
}
@Override
public String toConfigString()
{
var sb = new StringBuilder();
sb.append("\\\\\t");
sb.append(maxPoints.toPlainString());
if (baseMsg != null)
{
sb.append("\t");
sb.append(baseMsg);
}
for (var i = 0; i < text.length; i++)
{
sb.append("\n\t");
sb.append(points[i].toPlainString());
sb.append("\t");
sb.append(text[i]);
}
return sb.toString();
}
@Override
public String toResultHtml(HtmlContext hc)
{
return "<li" + hc.styleText(achievedPoints(hc.mc), maxPoints) + ">" + //
"<span" + hc.stylePts(achievedPoints(hc.mc), maxPoints) + ">" + //
achievedPoints(hc.mc) + "/" + maxPoints.toPlainString() + "P</span>" + //
(baseMsg == null ? text[getSelected()] : baseMsg + " (" + text[getSelected()] + ")") + "</li>";
}
}

View File

@ -25,16 +25,12 @@
\\ 5.0 \\ 5.0
5.0 Volle Punkte 5.0 Volle Punkte
2.5 Halbe Punkte 2.5 Halbe Punkte
50% Halbe Punkte in Prozent
1/3 Ein Drittel Punkte als Bruch
0 Null Punkte 0 Null Punkte
\\ 5.0 Text der immer angezeigt wird. Dadurch wird der Text bei den Punkten zur Begründung \\ 5.0 Text der immer angezeigt wird. Dadurch wird der Text bei den Punkten zur Begründung
5.0 Volle Punkte 5.0 Volle Punkte
2.5 Halbe Punkte 2.5 Halbe Punkte
50% Halbe Punkte in Prozent
1/3 Ein Drittel Punkte als Bruch
0 Null Punkte 0 Null Punkte
\\ 5.0 Text der immer angezeigt wird. Dadurch wird der Text bei den Punkten zur Begründung (Multi-Select anstatt Radio-Box, das kann nicht gemischt werden!) \\ 5.0 Text der immer angezeigt wird. Dadurch wird der Text bei den Punkten zur Begründung (Multi-Select anstatt Radio-Box. das kann nicht gemischt werden!)
[] 1.0 Ziel 1 [] 1.0 Ziel 1
[] 1.0 Ziel 2 [] 1.0 Ziel 2
[] 2.0 Ziel 3 [] 2.0 Ziel 3