From 06da8bebfeb606ae26305dd8701a2fa59c97704f Mon Sep 17 00:00:00 2001 From: Robert Melo Date: Mon, 6 Apr 2020 21:42:00 -0300 Subject: [PATCH] ICU-5938 Fix inaccurate output on RBNF demo sample - Replace the attribute type of the attribute from double to BigDecimal in order to format a number by using RBNF rules without rounding error issues. - A modification on < and > buttons (multiply/divide by 10) to also fix rounding error issues. --- .../com/ibm/icu/dev/demo/rbnf/RbnfDemo.java | 56 ++++++++++++++----- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/icu4j/demos/src/com/ibm/icu/dev/demo/rbnf/RbnfDemo.java b/icu4j/demos/src/com/ibm/icu/dev/demo/rbnf/RbnfDemo.java index e34479daa62..4afa2ea39be 100644 --- a/icu4j/demos/src/com/ibm/icu/dev/demo/rbnf/RbnfDemo.java +++ b/icu4j/demos/src/com/ibm/icu/dev/demo/rbnf/RbnfDemo.java @@ -45,6 +45,7 @@ import java.text.ParsePosition; import java.util.Locale; import com.ibm.icu.dev.demo.impl.DemoApplet; +import com.ibm.icu.math.BigDecimal; import com.ibm.icu.text.RuleBasedNumberFormat; public class RbnfDemo extends DemoApplet { @@ -66,10 +67,12 @@ public class RbnfDemo extends DemoApplet { new RbnfDemo().showDemo(); } + @Override protected Dimension getDefaultFrameSize(DemoApplet applet, Frame f) { return new Dimension(430,270); } + @Override protected Frame createDemoFrame(DemoApplet applet) { final Frame window = new Frame("Number Spellout Demo"); window.setSize(800, 600); @@ -89,7 +92,7 @@ public class RbnfDemo extends DemoApplet { populateRuleSetMenu(); numberFormatter = new DecimalFormat("#,##0.##########"); parsePosition = new ParsePosition(0); - theNumber = 0; + theNumber = BigDecimal.ZERO; numberField = new TextField(); numberField.setFont(new Font("Serif", Font.PLAIN, 24)); @@ -100,6 +103,7 @@ public class RbnfDemo extends DemoApplet { lenientParseButton = new Checkbox("Lenient parse", lenientParse); numberField.addTextListener(new TextListener() { + @Override public void textValueChanged(TextEvent e) { if (!numberFieldHasFocus) return; @@ -108,22 +112,24 @@ public class RbnfDemo extends DemoApplet { parsePosition.setIndex(0); Number temp = numberFormatter.parse(fieldText, parsePosition); if (temp == null || parsePosition.getIndex() == 0) { - theNumber = 0; + theNumber = BigDecimal.ZERO; textField.setText("PARSE ERROR"); } else { - theNumber = temp.doubleValue(); - textField.setText(spelloutFormatter.format(theNumber, ruleSetName)); + theNumber = new BigDecimal(fieldText); + textField.setText(spelloutFormatter.format(theNumber.doubleValue(), ruleSetName)); } } } ); numberField.addFocusListener(new FocusAdapter() { + @Override public void focusLost(FocusEvent e) { numberFieldHasFocus = false; numberField.setText(numberFormatter.format(theNumber)); } + @Override public void focusGained(FocusEvent e) { numberFieldHasFocus = true; numberField.selectAll(); @@ -131,14 +137,15 @@ public class RbnfDemo extends DemoApplet { } ); textField.addKeyListener(new KeyAdapter() { + @Override public void keyTyped(KeyEvent e) { if (e.getKeyChar() == '\t') { String fieldText = ((TextComponent)(e.getSource())).getText(); parsePosition.setIndex(0); - theNumber = spelloutFormatter.parse(fieldText, parsePosition) - .doubleValue(); + theNumber = new BigDecimal(spelloutFormatter.parse(fieldText, parsePosition) + .doubleValue()); if (parsePosition.getIndex() == 0) { - theNumber = 0; + theNumber = BigDecimal.ZERO; numberField.setText("PARSE ERROR"); textField.selectAll(); } @@ -156,11 +163,12 @@ public class RbnfDemo extends DemoApplet { } ); textField.addFocusListener(new FocusAdapter() { + @Override public void focusLost(FocusEvent e) { String fieldText = ((TextComponent)(e.getSource())).getText(); parsePosition.setIndex(0); - theNumber = spelloutFormatter.parse(fieldText, parsePosition) - .doubleValue(); + theNumber = new BigDecimal(spelloutFormatter.parse(fieldText, parsePosition) + .doubleValue()); if (parsePosition.getIndex() == 0) numberField.setText("PARSE ERROR"); else @@ -168,12 +176,14 @@ public class RbnfDemo extends DemoApplet { textField.setText(textField.getText()); // textField.repaint() didn't work right } + @Override public void focusGained(FocusEvent e) { textField.selectAll(); } } ); rulesField.addKeyListener(new KeyAdapter() { + @Override public void keyTyped(KeyEvent e) { if (e.getKeyChar() == '\t') { String fieldText = ((TextComponent)(e.getSource())).getText(); @@ -201,6 +211,7 @@ public class RbnfDemo extends DemoApplet { } ); rulesField.addFocusListener(new FocusAdapter() { + @Override public void focusLost(FocusEvent e) { String fieldText = ((TextComponent)(e.getSource())).getText(); if (formatterMenu.getSelectedItem().equals("Custom") || !fieldText.equals( @@ -223,6 +234,7 @@ public class RbnfDemo extends DemoApplet { } ); lenientParseButton.addItemListener(new ItemListener() { + @Override public void itemStateChanged(ItemEvent e) { lenientParse = lenientParseButton.getState(); spelloutFormatter.setLenientParseMode(lenientParse); @@ -231,7 +243,7 @@ public class RbnfDemo extends DemoApplet { numberField.setText(numberFormatter.format(theNumber)); numberField.selectAll(); - textField.setText(spelloutFormatter.format(theNumber, ruleSetName)); + textField.setText(spelloutFormatter.format(theNumber.doubleValue(), ruleSetName)); Panel leftPanel = new Panel(); leftPanel.setLayout(new BorderLayout()); @@ -247,6 +259,7 @@ public class RbnfDemo extends DemoApplet { panel2.setLayout(new GridLayout(3, 3)); Button button = new Button("+100"); button.addActionListener( new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { roll(100); } @@ -254,6 +267,7 @@ public class RbnfDemo extends DemoApplet { panel2.add(button); button = new Button("+10"); button.addActionListener( new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { roll(10); } @@ -261,6 +275,7 @@ public class RbnfDemo extends DemoApplet { panel2.add(button); button = new Button("+1"); button.addActionListener( new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { roll(1); } @@ -268,8 +283,9 @@ public class RbnfDemo extends DemoApplet { panel2.add(button); button = new Button("<"); button.addActionListener( new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { - theNumber *= 10; + theNumber = new BigDecimal(theNumber.toString()).multiply(new BigDecimal("10")); redisplay(); } } ); @@ -277,14 +293,16 @@ public class RbnfDemo extends DemoApplet { panel2.add(new Panel()); button = new Button(">"); button.addActionListener( new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { - theNumber /= 10; + theNumber = new BigDecimal(theNumber.toString()).multiply(new BigDecimal("0.1")); redisplay(); } } ); panel2.add(button); button = new Button("-100"); button.addActionListener( new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { roll(-100); } @@ -292,6 +310,7 @@ public class RbnfDemo extends DemoApplet { panel2.add(button); button = new Button("-10"); button.addActionListener( new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { roll(-10); } @@ -299,6 +318,7 @@ public class RbnfDemo extends DemoApplet { panel2.add(button); button = new Button("-1"); button.addActionListener( new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { roll(-1); } @@ -315,6 +335,7 @@ public class RbnfDemo extends DemoApplet { formatterMenu.addItem(RbnfSampleRuleSets.sampleRuleSetNames[i]); formatterMenu.addItem("Custom"); formatterMenu.addItemListener(new ItemListener() { + @Override public void itemStateChanged(ItemEvent e) { Choice source = (Choice)(e.getSource()); int item = source.getSelectedIndex(); @@ -344,6 +365,7 @@ public class RbnfDemo extends DemoApplet { populateRuleSetMenu(); ruleSetMenu.addItemListener(new ItemListener() { + @Override public void itemStateChanged(ItemEvent e) { ruleSetName = ruleSetMenu.getSelectedItem(); redisplay(); @@ -370,6 +392,7 @@ public class RbnfDemo extends DemoApplet { final DemoApplet theApplet = applet; window.addWindowListener( new WindowAdapter() { + @Override public void windowClosing(WindowEvent e) { setVisible(false); window.dispose(); @@ -383,13 +406,13 @@ public class RbnfDemo extends DemoApplet { } void roll(int delta) { - theNumber += delta; + theNumber = theNumber.add(new BigDecimal(delta)); redisplay(); } void redisplay() { numberField.setText(numberFormatter.format(theNumber)); - textField.setText(spelloutFormatter.format(theNumber, ruleSetName)); + textField.setText(spelloutFormatter.format(theNumber.doubleValue(), ruleSetName)); } void makeNewSpelloutFormatter() { @@ -444,7 +467,7 @@ public class RbnfDemo extends DemoApplet { private boolean lenientParse = true; - private double theNumber = 0; + private BigDecimal theNumber = BigDecimal.ZERO; // private boolean canEdit = true; private Choice formatterMenu; @@ -471,6 +494,7 @@ class DemoTextField extends Component { return text; } + @Override public void paint(Graphics g) { Font font = getFont(); FontMetrics fm = g.getFontMetrics(); @@ -542,10 +566,12 @@ class DemoTextFieldHolder extends Panel { add(sp, "ScrollPane"); } + @Override public void addFocusListener(FocusListener l) { tf1.addFocusListener(l); } + @Override public void addKeyListener(KeyListener l) { tf1.addKeyListener(l); }