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