diff --git a/src/studio/kdb/KFormat.java b/src/studio/kdb/KFormat.java index 0c869ee..9973a1d 100644 --- a/src/studio/kdb/KFormat.java +++ b/src/studio/kdb/KFormat.java @@ -1,6 +1,5 @@ package studio.kdb; -import java.text.DecimalFormat; import java.text.FieldPosition; import java.text.NumberFormat; import java.text.ParsePosition; @@ -11,24 +10,11 @@ public class KFormat extends NumberFormat { private KType type; - private static final DecimalFormat fractionFormat = new DecimalFormat("+0.#####;-0.#####"); - public KFormat(KType type) { this.type = type; } - @Override - public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) { - return format((double)number, toAppendTo, pos); - } - - @Override - public Number parse(String source, ParsePosition parsePosition) { - throw new UnsupportedOperationException(); - } - - @Override - public StringBuffer format(double value, StringBuffer toAppendTo, FieldPosition pos) { + public static String format(KType type, double value) { K.KBase kValue; if (type == KType.Int || type == KType.Double || @@ -87,8 +73,22 @@ public StringBuffer format(double value, StringBuffer toAppendTo, FieldPosition } } - toAppendTo.append(kValue.toString(KFormatContext.NO_TYPE)); + return kValue.toString(KFormatContext.NO_TYPE); + } + @Override + public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) { + return format((double)number, toAppendTo, pos); + } + + @Override + public Number parse(String source, ParsePosition parsePosition) { + throw new UnsupportedOperationException(); + } + + @Override + public StringBuffer format(double value, StringBuffer toAppendTo, FieldPosition pos) { + toAppendTo.append(format(type, value)); return toAppendTo; } diff --git a/src/studio/ui/chart/Chart.java b/src/studio/ui/chart/Chart.java index d423024..6aa5d50 100755 --- a/src/studio/ui/chart/Chart.java +++ b/src/studio/ui/chart/Chart.java @@ -60,8 +60,8 @@ public class Chart implements ComponentListener { private final static Set supportedClasses = new HashSet<>(); static { - supportedClasses.addAll(DurationEditor.VALUE_CLASSES); - supportedClasses.addAll(DurationEditor.TEMPORAL_CLASSES); + supportedClasses.addAll(Editor.VALUE_CLASSES); + supportedClasses.addAll(Editor.TEMPORAL_CLASSES); } private static StandardChartTheme currentTheme = new StandardChartTheme("JFree"); diff --git a/src/studio/ui/chart/DurationEditor.java b/src/studio/ui/chart/Editor.java similarity index 68% rename from src/studio/ui/chart/DurationEditor.java rename to src/studio/ui/chart/Editor.java index e943ccc..2555444 100644 --- a/src/studio/ui/chart/DurationEditor.java +++ b/src/studio/ui/chart/Editor.java @@ -1,6 +1,8 @@ package studio.ui.chart; +import studio.kdb.KFormat; import studio.kdb.KType; +import studio.kdb.Parser; import studio.ui.chart.event.ValueChangedEvent; import studio.ui.chart.event.ValueChangedListener; @@ -13,7 +15,7 @@ import java.util.List; -public class DurationEditor extends JPanel { +public class Editor extends JPanel { public static final List VALUE_CLASSES = List.of( @@ -38,13 +40,19 @@ public class DurationEditor extends JPanel { private final EventListenerList listenerList = new EventListenerList(); - public static DurationEditor create(KType unitType) { - if (VALUE_CLASSES.contains(unitType)) return new DurationEditor(); + public static Editor createDurationEditor(KType unitType) { + if (VALUE_CLASSES.contains(unitType)) return new Editor(unitType, true); if (TEMPORAL_CLASSES.contains(unitType)) return new TimespanEditor(unitType); - throw new UnsupportedOperationException("DurationEditor for type " + unitType + " is not supported"); + throw new UnsupportedOperationException("Editor for type " + unitType + " is not supported"); } + public static Editor createEditor(KType unitType) { + if (VALUE_CLASSES.contains(unitType)) return new Editor(unitType, true); + if (TEMPORAL_CLASSES.contains(unitType)) return new Editor(unitType, false); + + throw new UnsupportedOperationException("Editor for type " + unitType + " is not supported"); + } public void addValueChangedListener(ValueChangedListener listener) { listenerList.add(ValueChangedListener.class, listener); @@ -67,9 +75,13 @@ protected void notifyValueChanged() { protected final JTextField txtValue = new JTextField(); private double value = Double.NaN; + protected final KType unitType; + private final boolean numeric; - protected DurationEditor() { + protected Editor(KType uniteType, boolean numeric) { super(new BorderLayout()); + this.unitType = uniteType; + this.numeric = numeric; add(txtValue, BorderLayout.CENTER); txtValue.addActionListener(this::txtValueChanged); @@ -94,7 +106,11 @@ public void setValue(double value) { } protected void refresh() { - txtValue.setText("" + value); + if (numeric) { + txtValue.setText("" + value); + } else { + txtValue.setText(KFormat.format(unitType, value)); + } } protected void txtValueChanged(double newValue) { @@ -103,14 +119,23 @@ protected void txtValueChanged(double newValue) { private void txtValueChanged(ActionEvent event) { boolean error = false; + double v = value; try { - double v = Double.parseDouble(txtValue.getText()); - txtValueChanged(v); + if (numeric) { + v = Double.parseDouble(txtValue.getText()); + } else { + v = Parser.parse(unitType, txtValue.getText()); + error = Double.isNaN(v); + } } catch (NumberFormatException e) { error = true; } - refresh(); - if (!error) { + + if (error) { + refresh(); + } else { + txtValueChanged(v); + refresh(); notifyValueChanged(); } } diff --git a/src/studio/ui/chart/LineInfoFrame.java b/src/studio/ui/chart/LineInfoFrame.java index 2329d99..6a0d5df 100644 --- a/src/studio/ui/chart/LineInfoFrame.java +++ b/src/studio/ui/chart/LineInfoFrame.java @@ -5,8 +5,6 @@ import javax.swing.*; import java.awt.*; -import java.awt.event.FocusAdapter; -import java.awt.event.FocusEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.function.DoubleConsumer; @@ -19,10 +17,10 @@ public class LineInfoFrame extends JFrame { private final JLabel lblX = new JLabel(""); private final JLabel lblY = new JLabel(""); private final JTextField txtTitle = new JTextField(); - private final DurationEditor txtDX; - private final DurationEditor txtDY; - private final JTextField txtX = new JTextField(); - private final JTextField txtY = new JTextField(); + private final Editor txtDX; + private final Editor txtDY; + private final Editor txtX; + private final Editor txtY; private double dx = 1; private double dy = Double.NaN; @@ -33,8 +31,11 @@ public class LineInfoFrame extends JFrame { public LineInfoFrame(Line line, KType xType, KType yType) { this.line = line; - txtDX = DurationEditor.create(xType); - txtDY = DurationEditor.create(yType); + txtDX = Editor.createDurationEditor(xType); + txtDY = Editor.createDurationEditor(yType); + + txtX = Editor.createEditor(xType); + txtY = Editor.createEditor(yType); line.addChangeListener(e -> refresh()); initComponents(); @@ -54,26 +55,7 @@ public void mousePressed(MouseEvent e) { return panel; } - private void performAction(JTextField textField, DoubleConsumer action) { - try { - double value = Double.parseDouble(textField.getText()); - action.accept(value); - } catch (NumberFormatException e) {} - refresh(); - } - - private JTextField withAction(JTextField textField, DoubleConsumer action) { - textField.addActionListener(e -> performAction(textField, action)); - textField.addFocusListener(new FocusAdapter() { - @Override - public void focusLost(FocusEvent e) { - performAction(textField, action); - } - }); - return textField; - } - - private DurationEditor withAction(DurationEditor editor, DoubleConsumer action) { + private Editor withAction(Editor editor, DoubleConsumer action) { editor.addValueChangedListener(e -> { action.accept(e.getValue()); refresh(); @@ -152,8 +134,8 @@ private void refresh() { txtDX.setValue(dx); txtDY.setValue(dy); - txtX.setText("" + x); - txtY.setText("" + y); + txtX.setValue(x); + txtY.setValue(y); txtTitle.setText(line.getTitle()); diff --git a/src/studio/ui/chart/TimespanEditor.java b/src/studio/ui/chart/TimespanEditor.java index a3f132d..5c138e9 100644 --- a/src/studio/ui/chart/TimespanEditor.java +++ b/src/studio/ui/chart/TimespanEditor.java @@ -7,16 +7,15 @@ import java.awt.*; import java.time.temporal.ChronoUnit; -public class TimespanEditor extends DurationEditor { +public class TimespanEditor extends Editor { - private final KType unittype; private K.KTimespan value = K.KTimespan.NULL; private final JComboBox comboUnit = new JComboBox<>(K.KTimespan.getSupportedUnits()); public TimespanEditor(KType unitType) { - this.unittype = unitType; + super(unitType, false); add(comboUnit, BorderLayout.EAST); comboUnit.addActionListener(e -> refresh()); @@ -38,7 +37,7 @@ private void unitAutoSelect(K.KTimespan value) { } public void setValue(double value) { - K.KTimespan newValue = K.KTimespan.duration(value, unittype); + K.KTimespan newValue = K.KTimespan.duration(value, unitType); if (newValue.equals(this.value)) return; if (this.value.equals(K.KTimespan.NULL)) { @@ -52,7 +51,7 @@ public void setValue(double value) { } public double getValue() { - return value.toUnitValue(unittype); + return value.toUnitValue(unitType); } protected void refresh() { diff --git a/test/studio/kdb/ParserTest.java b/test/studio/kdb/ParserTest.java index 65de086..3ffc7e4 100644 --- a/test/studio/kdb/ParserTest.java +++ b/test/studio/kdb/ParserTest.java @@ -55,8 +55,7 @@ public void testDuration() { private void checkParsing(KType type, String expected, String text) { double value = Parser.parse(type, text); - String formatted = new KFormat(type).format(value, new StringBuffer(), null).toString(); - + String formatted = KFormat.format(type,value); assertEquals(expected, formatted, "assert for type: " + type); }