2 *******************************************************************************
3 * Copyright (C) 1996-2010, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 *******************************************************************************
7 package com.ibm.icu.dev.demo.rbnf;
9 import java.awt.BorderLayout;
10 import java.awt.Button;
11 import java.awt.CardLayout;
12 import java.awt.Checkbox;
13 import java.awt.Choice;
14 import java.awt.Component;
15 import java.awt.Dimension;
17 import java.awt.FontMetrics;
18 import java.awt.Frame;
19 import java.awt.Graphics;
20 import java.awt.GridLayout;
21 import java.awt.Panel;
22 import java.awt.ScrollPane;
23 import java.awt.TextArea;
24 import java.awt.TextComponent;
25 import java.awt.TextField;
26 import java.awt.event.ActionEvent;
27 import java.awt.event.ActionListener;
28 import java.awt.event.FocusAdapter;
29 import java.awt.event.FocusEvent;
30 import java.awt.event.FocusListener;
31 import java.awt.event.ItemEvent;
32 import java.awt.event.ItemListener;
33 import java.awt.event.KeyAdapter;
34 import java.awt.event.KeyEvent;
35 import java.awt.event.KeyListener;
36 import java.awt.event.TextEvent;
37 import java.awt.event.TextListener;
38 import java.awt.event.WindowAdapter;
39 import java.awt.event.WindowEvent;
40 import java.text.BreakIterator;
41 import java.text.DecimalFormat;
42 import java.text.ParsePosition;
43 import java.util.Locale;
45 import com.ibm.icu.dev.demo.impl.DemoApplet;
46 import com.ibm.icu.text.RuleBasedNumberFormat;
48 public class RbnfDemo extends DemoApplet {
52 private static final long serialVersionUID = -9119861296873763536L;
55 * Puts a copyright in the .class file
57 // private static final String copyrightNotice
58 // = "Copyright \u00a91997-1998 IBM Corp. All rights reserved.";
61 * code to run the demo as an application
63 public static void main(String[] argv) {
64 new RbnfDemo().showDemo();
67 protected Dimension getDefaultFrameSize(DemoApplet applet, Frame f) {
68 return new Dimension(430,270);
71 protected Frame createDemoFrame(DemoApplet applet) {
72 final Frame window = new Frame("Number Spellout Demo");
73 window.setSize(800, 600);
74 window.setLayout(new BorderLayout());
76 Panel mainPanel = new Panel();
77 mainPanel.setLayout(new GridLayout(1,2));
79 commentaryField = new TextArea("", 0, 0, TextArea.SCROLLBARS_VERTICAL_ONLY);
80 commentaryField.setSize(800, 50);
81 commentaryField.setText(RbnfSampleRuleSets.sampleRuleSetCommentary[0]);
82 commentaryField.setEditable(false);
83 commentaryField.setFont(new Font("Helvetica", Font.PLAIN, 14));
85 spelloutFormatter = new RuleBasedNumberFormat(RbnfSampleRuleSets.usEnglish, Locale.US);
86 spelloutFormatter.setLenientParseMode(lenientParse);
87 populateRuleSetMenu();
88 numberFormatter = new DecimalFormat("#,##0.##########");
89 parsePosition = new ParsePosition(0);
92 numberField = new TextField();
93 numberField.setFont(new Font("Serif", Font.PLAIN, 24));
94 textField = new DemoTextFieldHolder();
95 textField.setFont(new Font("Serif", Font.PLAIN, 24));
96 rulesField = new DemoTextFieldHolder();
97 rulesField.setFont(new Font("Serif", Font.PLAIN, 14));
98 lenientParseButton = new Checkbox("Lenient parse", lenientParse);
100 numberField.addTextListener(new TextListener() {
101 public void textValueChanged(TextEvent e) {
102 if (!numberFieldHasFocus)
105 String fieldText = ((TextComponent)(e.getSource())).getText();
106 parsePosition.setIndex(0);
107 Number temp = numberFormatter.parse(fieldText, parsePosition);
108 if (temp == null || parsePosition.getIndex() == 0) {
110 textField.setText("PARSE ERROR");
113 theNumber = temp.doubleValue();
114 textField.setText(spelloutFormatter.format(theNumber, ruleSetName));
119 numberField.addFocusListener(new FocusAdapter() {
120 public void focusLost(FocusEvent e) {
121 numberFieldHasFocus = false;
122 numberField.setText(numberFormatter.format(theNumber));
125 public void focusGained(FocusEvent e) {
126 numberFieldHasFocus = true;
127 numberField.selectAll();
131 textField.addKeyListener(new KeyAdapter() {
132 public void keyTyped(KeyEvent e) {
133 if (e.getKeyChar() == '\t') {
134 String fieldText = ((TextComponent)(e.getSource())).getText();
135 parsePosition.setIndex(0);
136 theNumber = spelloutFormatter.parse(fieldText, parsePosition)
138 if (parsePosition.getIndex() == 0) {
140 numberField.setText("PARSE ERROR");
141 textField.selectAll();
143 else if (parsePosition.getIndex() < fieldText.length()) {
144 textField.select(parsePosition.getIndex(), fieldText.length());
145 numberField.setText(numberFormatter.format(theNumber));
148 textField.selectAll();
149 numberField.setText(numberFormatter.format(theNumber));
156 textField.addFocusListener(new FocusAdapter() {
157 public void focusLost(FocusEvent e) {
158 String fieldText = ((TextComponent)(e.getSource())).getText();
159 parsePosition.setIndex(0);
160 theNumber = spelloutFormatter.parse(fieldText, parsePosition)
162 if (parsePosition.getIndex() == 0)
163 numberField.setText("PARSE ERROR");
165 numberField.setText(numberFormatter.format(theNumber));
166 textField.setText(textField.getText()); // textField.repaint() didn't work right
169 public void focusGained(FocusEvent e) {
170 textField.selectAll();
174 rulesField.addKeyListener(new KeyAdapter() {
175 public void keyTyped(KeyEvent e) {
176 if (e.getKeyChar() == '\t') {
177 String fieldText = ((TextComponent)(e.getSource())).getText();
178 if (formatterMenu.getSelectedItem().equals("Custom") || !fieldText.equals(
179 RbnfSampleRuleSets.sampleRuleSets[formatterMenu.getSelectedIndex()])) {
181 RuleBasedNumberFormat temp = new RuleBasedNumberFormat(fieldText);
182 temp.setLenientParseMode(lenientParse);
183 populateRuleSetMenu();
184 spelloutFormatter = temp;
185 customRuleSet = fieldText;
186 formatterMenu.select("Custom");
187 commentaryField.setText(RbnfSampleRuleSets.
188 sampleRuleSetCommentary[RbnfSampleRuleSets.
189 sampleRuleSetCommentary.length - 1]);
192 catch (Exception x) {
193 textField.setText(x.toString());
201 rulesField.addFocusListener(new FocusAdapter() {
202 public void focusLost(FocusEvent e) {
203 String fieldText = ((TextComponent)(e.getSource())).getText();
204 if (formatterMenu.getSelectedItem().equals("Custom") || !fieldText.equals(
205 RbnfSampleRuleSets.sampleRuleSets[formatterMenu.getSelectedIndex()])) {
207 RuleBasedNumberFormat temp = new RuleBasedNumberFormat(fieldText);
208 temp.setLenientParseMode(lenientParse);
209 populateRuleSetMenu();
210 spelloutFormatter = temp;
211 customRuleSet = fieldText;
212 formatterMenu.select("Custom");
215 catch (Exception x) {
216 textField.setText(x.toString());
219 rulesField.setText(rulesField.getText()); // rulesField.repaint() didn't work right
223 lenientParseButton.addItemListener(new ItemListener() {
224 public void itemStateChanged(ItemEvent e) {
225 lenientParse = lenientParseButton.getState();
226 spelloutFormatter.setLenientParseMode(lenientParse);
230 numberField.setText(numberFormatter.format(theNumber));
231 numberField.selectAll();
232 textField.setText(spelloutFormatter.format(theNumber, ruleSetName));
234 Panel leftPanel = new Panel();
235 leftPanel.setLayout(new BorderLayout());
236 Panel panel = new Panel();
237 panel.setLayout(new BorderLayout());
238 Panel panel1 = new Panel();
239 panel1.setLayout(new GridLayout(3, 1));
240 panel1.add(new Panel());
241 panel1.add(numberField, "Center");
242 panel1.add(lenientParseButton);
243 panel.add(panel1, "Center");
244 Panel panel2 = new Panel();
245 panel2.setLayout(new GridLayout(3, 3));
246 Button button = new Button("+100");
247 button.addActionListener( new ActionListener() {
248 public void actionPerformed(ActionEvent e) {
253 button = new Button("+10");
254 button.addActionListener( new ActionListener() {
255 public void actionPerformed(ActionEvent e) {
260 button = new Button("+1");
261 button.addActionListener( new ActionListener() {
262 public void actionPerformed(ActionEvent e) {
267 button = new Button("<");
268 button.addActionListener( new ActionListener() {
269 public void actionPerformed(ActionEvent e) {
275 panel2.add(new Panel());
276 button = new Button(">");
277 button.addActionListener( new ActionListener() {
278 public void actionPerformed(ActionEvent e) {
284 button = new Button("-100");
285 button.addActionListener( new ActionListener() {
286 public void actionPerformed(ActionEvent e) {
291 button = new Button("-10");
292 button.addActionListener( new ActionListener() {
293 public void actionPerformed(ActionEvent e) {
298 button = new Button("-1");
299 button.addActionListener( new ActionListener() {
300 public void actionPerformed(ActionEvent e) {
305 panel.add(panel2, "East");
306 leftPanel.add(panel, "North");
307 leftPanel.add(textField, "Center");
309 Panel rightPanel = new Panel();
310 rightPanel.setLayout(new BorderLayout());
311 formatterMenu = new Choice();
312 for (int i = 0; i < RbnfSampleRuleSets.sampleRuleSetNames.length; i++)
313 formatterMenu.addItem(RbnfSampleRuleSets.sampleRuleSetNames[i]);
314 formatterMenu.addItem("Custom");
315 formatterMenu.addItemListener(new ItemListener() {
316 public void itemStateChanged(ItemEvent e) {
317 Choice source = (Choice)(e.getSource());
318 int item = source.getSelectedIndex();
319 Locale locale = RbnfSampleRuleSets.sampleRuleSetLocales[item];
321 commentaryField.setText(RbnfSampleRuleSets.
322 sampleRuleSetCommentary[item]);
324 if (locale != null && (locale.getLanguage().equals("iw")
325 || locale.getLanguage().equals("ru") || locale.getLanguage().equals("ja")
326 || locale.getLanguage().equals("el")
327 || locale.getLanguage().equals("zh"))) {
328 textField.togglePanes(false);
329 rulesField.togglePanes(false);
332 textField.togglePanes(true);
333 rulesField.togglePanes(true);
336 makeNewSpelloutFormatter();
341 ruleSetMenu = new Choice();
342 populateRuleSetMenu();
344 ruleSetMenu.addItemListener(new ItemListener() {
345 public void itemStateChanged(ItemEvent e) {
346 ruleSetName = ruleSetMenu.getSelectedItem();
351 Panel menuPanel = new Panel();
352 menuPanel.setLayout(new GridLayout(1, 2));
353 menuPanel.add(formatterMenu);
354 menuPanel.add(ruleSetMenu);
355 rightPanel.add(menuPanel, "North");
357 rulesField.setText(RbnfSampleRuleSets.sampleRuleSets[formatterMenu.getSelectedIndex()]);
358 rightPanel.add(rulesField, "Center");
360 mainPanel.add(leftPanel);
361 mainPanel.add(rightPanel);
363 window.add(mainPanel, "Center");
364 window.add(commentaryField, "South");
368 final DemoApplet theApplet = applet;
369 window.addWindowListener(
370 new WindowAdapter() {
371 public void windowClosing(WindowEvent e) {
375 if (theApplet != null) {
376 theApplet.demoClosed();
377 } else System.exit(0);
383 void roll(int delta) {
389 numberField.setText(numberFormatter.format(theNumber));
390 textField.setText(spelloutFormatter.format(theNumber, ruleSetName));
393 void makeNewSpelloutFormatter() {
394 int item = formatterMenu.getSelectedIndex();
395 String formatterMenuItem = formatterMenu.getSelectedItem();
397 if (formatterMenuItem.equals("Custom")) {
398 rulesField.setText(customRuleSet);
399 spelloutFormatter = new RuleBasedNumberFormat(customRuleSet);
402 rulesField.setText(RbnfSampleRuleSets.sampleRuleSets[item]);
404 Locale locale = RbnfSampleRuleSets.sampleRuleSetLocales[item];
406 locale = Locale.getDefault();
408 spelloutFormatter = new RuleBasedNumberFormat(RbnfSampleRuleSets.
409 sampleRuleSets[item], locale);
411 spelloutFormatter.setLenientParseMode(lenientParse);
412 populateRuleSetMenu();
415 void populateRuleSetMenu() {
416 String[] ruleSetNames = spelloutFormatter.getRuleSetNames();
418 if (ruleSetMenu != null) {
419 ruleSetMenu.removeAll();
420 for (int i = 0; i < ruleSetNames.length; i++)
421 ruleSetMenu.addItem(ruleSetNames[i]);
423 ruleSetName = ruleSetMenu.getSelectedItem();
426 ruleSetName = ruleSetNames[0];
429 // private Frame demoWindow = null;
431 private TextComponent numberField;
432 private DemoTextFieldHolder textField;
433 private DemoTextFieldHolder rulesField;
434 private TextComponent commentaryField;
435 private Checkbox lenientParseButton;
437 private boolean numberFieldHasFocus = true;
439 private RuleBasedNumberFormat spelloutFormatter;
440 private DecimalFormat numberFormatter;
441 private ParsePosition parsePosition;
443 private boolean lenientParse = true;
445 private double theNumber = 0;
446 // private boolean canEdit = true;
448 private Choice formatterMenu;
449 private Choice ruleSetMenu;
450 private String ruleSetName;
452 private String customRuleSet = "NO RULES!";
455 class DemoTextField extends Component {
459 private static final long serialVersionUID = -7947090021239472658L;
460 public DemoTextField() {
463 public void setText(String text) {
468 public String getText() {
472 public void paint(Graphics g) {
473 Font font = getFont();
474 FontMetrics fm = g.getFontMetrics();
476 String txt = getText();
477 BreakIterator bi = BreakIterator.getLineInstance();
479 int lineHeight = fm.getHeight();
480 int width = getSize().width;
481 int penY = fm.getAscent();
483 int tempLineEnd = bi.first();
488 while (lineStart < txt.length()) {
489 maxLineEnd = txt.indexOf('\n', lineStart);
490 if (maxLineEnd == -1)
491 maxLineEnd = Integer.MAX_VALUE;
492 while (tempLineEnd != BreakIterator.DONE && fm.stringWidth(txt.substring(
493 lineStart, tempLineEnd)) < width) {
494 lineEnd = tempLineEnd;
495 tempLineEnd = bi.next();
497 if (lineStart >= lineEnd) {
498 if (tempLineEnd == BreakIterator.DONE)
499 lineEnd = txt.length();
501 lineEnd = tempLineEnd;
503 if (lineEnd > maxLineEnd)
504 lineEnd = maxLineEnd;
505 g.drawString(txt.substring(lineStart, lineEnd), 0, penY);
507 totalHeight += lineHeight;
509 if (lineStart < txt.length() && txt.charAt(lineStart) == '\n')
515 public Dimension getPreferredSize() {
516 Dimension size = getParent().getSize();
517 return new Dimension(size.width, totalHeight);
522 private int totalHeight;
525 class DemoTextFieldHolder extends Panel {
529 private static final long serialVersionUID = 7514498764062569858L;
530 public DemoTextFieldHolder() {
531 tf1 = new TextArea("", 0, 0, TextArea.SCROLLBARS_VERTICAL_ONLY);
532 tf2 = new DemoTextField();
533 sp = new ScrollPane();
535 setLayout(new CardLayout());
537 sp.add(tf2, "TextField1");
538 sp.setVisible(false);
539 add(tf1, "TestField2");
540 add(sp, "ScrollPane");
543 public void addFocusListener(FocusListener l) {
544 tf1.addFocusListener(l);
547 public void addKeyListener(KeyListener l) {
548 tf1.addKeyListener(l);
551 public void setText(String text) {
556 public String getText() {
557 return tf1.getText();
560 public void select(int start, int end) {
561 tf1.select(start, end);
564 public void selectAll() {
568 public void togglePanes(boolean canShowRealTextField) {
569 if (canShowRealTextField != showingRealTextField) {
570 CardLayout layout = (CardLayout)(getLayout());
572 showingRealTextField = canShowRealTextField;
576 private TextArea tf1 = null;
577 private DemoTextField tf2 = null;
578 private ScrollPane sp = null;
579 private boolean showingRealTextField = true;