1/* 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * - Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * - Neither the name of Oracle nor the names of its 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32/* 33 * This source code is provided to illustrate the usage of a given feature 34 * or technique and has been deliberately simplified. Additional steps 35 * required for a production-quality application, such as security checks, 36 * input validation and proper error handling, might not be present in 37 * this sample code. 38 */ 39 40 41 42import java.applet.Applet; 43import java.awt.*; 44import java.awt.event.*; 45import java.io.*; 46import java.net.*; 47 48 49@SuppressWarnings("serial") 50public class SpreadSheet extends Applet implements MouseListener, KeyListener { 51 52 String title; 53 Font titleFont; 54 Color cellColor; 55 Color inputColor; 56 int cellWidth = 100; 57 int cellHeight = 15; 58 int titleHeight = 15; 59 int rowLabelWidth = 15; 60 Font inputFont; 61 boolean isStopped = false; 62 boolean fullUpdate = true; 63 int rows; 64 int columns; 65 int currentKey = -1; 66 int selectedRow = -1; 67 int selectedColumn = -1; 68 SpreadSheetInput inputArea; 69 Cell cells[][]; 70 Cell current = null; 71 72 @Override 73 public synchronized void init() { 74 String rs; 75 76 cellColor = Color.white; 77 inputColor = new Color(100, 100, 225); 78 inputFont = new Font("Monospaced", Font.PLAIN, 10); 79 titleFont = new Font("Monospaced", Font.BOLD, 12); 80 title = getParameter("title"); 81 if (title == null) { 82 title = "Spreadsheet"; 83 } 84 rs = getParameter("rows"); 85 if (rs == null) { 86 rows = 9; 87 } else { 88 rows = Integer.parseInt(rs); 89 } 90 rs = getParameter("columns"); 91 if (rs == null) { 92 columns = 5; 93 } else { 94 columns = Integer.parseInt(rs); 95 } 96 cells = new Cell[rows][columns]; 97 char l[] = new char[1]; 98 for (int i = 0; i < rows; i++) { 99 for (int j = 0; j < columns; j++) { 100 101 cells[i][j] = new Cell(this, 102 Color.lightGray, 103 Color.black, 104 cellColor, 105 cellWidth - 2, 106 cellHeight - 2); 107 l[0] = (char) ((int) 'a' + j); 108 rs = getParameter("" + new String(l) + (i + 1)); 109 if (rs != null) { 110 cells[i][j].setUnparsedValue(rs); 111 } 112 } 113 } 114 115 Dimension d = getSize(); 116 inputArea = new SpreadSheetInput(null, this, d.width - 2, cellHeight - 1, 117 inputColor, Color.white); 118 resize(columns * cellWidth + rowLabelWidth, 119 (rows + 3) * cellHeight + titleHeight); 120 addMouseListener(this); 121 addKeyListener(this); 122 } 123 124 public void setCurrentValue(float val) { 125 if (selectedRow == -1 || selectedColumn == -1) { 126 return; 127 } 128 cells[selectedRow][selectedColumn].setValue(val); 129 repaint(); 130 } 131 132 @Override 133 public void stop() { 134 isStopped = true; 135 } 136 137 @Override 138 public void start() { 139 isStopped = false; 140 } 141 142 @Override 143 public void destroy() { 144 for (int i = 0; i < rows; i++) { 145 for (int j = 0; j < columns; j++) { 146 if (cells[i][j].type == Cell.URL) { 147 cells[i][j].updaterThread.run = false; 148 } 149 } 150 } 151 } 152 153 public void setCurrentValue(int type, String val) { 154 if (selectedRow == -1 || selectedColumn == -1) { 155 return; 156 } 157 cells[selectedRow][selectedColumn].setValue(type, val); 158 repaint(); 159 } 160 161 @Override 162 public void update(Graphics g) { 163 if (!fullUpdate) { 164 int cx, cy; 165 166 g.setFont(titleFont); 167 for (int i = 0; i < rows; i++) { 168 for (int j = 0; j < columns; j++) { 169 if (cells[i][j].needRedisplay) { 170 cx = (j * cellWidth) + 2 + rowLabelWidth; 171 cy = ((i + 1) * cellHeight) + 2 + titleHeight; 172 cells[i][j].paint(g, cx, cy); 173 } 174 } 175 } 176 } else { 177 paint(g); 178 fullUpdate = false; 179 } 180 } 181 182 public void recalculate() { 183 int i, j; 184 185 //System.out.println("SpreadSheet.recalculate"); 186 for (i = 0; i < rows; i++) { 187 for (j = 0; j < columns; j++) { 188 if (cells[i][j] != null && cells[i][j].type == Cell.FORMULA) { 189 cells[i][j].setRawValue(evaluateFormula( 190 cells[i][j].parseRoot)); 191 cells[i][j].needRedisplay = true; 192 } 193 } 194 } 195 repaint(); 196 } 197 198 float evaluateFormula(Node n) { 199 float val = 0.0f; 200 201 //System.out.println("evaluateFormula:"); 202 //n.print(3); 203 if (n == null) { 204 //System.out.println("Null node"); 205 return val; 206 } 207 switch (n.type) { 208 case Node.OP: 209 val = evaluateFormula(n.left); 210 switch (n.op) { 211 case '+': 212 val += evaluateFormula(n.right); 213 break; 214 case '*': 215 val *= evaluateFormula(n.right); 216 break; 217 case '-': 218 val -= evaluateFormula(n.right); 219 break; 220 case '/': 221 val /= evaluateFormula(n.right); 222 break; 223 } 224 break; 225 case Node.VALUE: 226 //System.out.println("=>" + n.value); 227 return n.value; 228 case Node.CELL: 229 if (cells[n.row][n.column] == null) { 230 //System.out.println("NULL at 193"); 231 } else { 232 //System.out.println("=>" + cells[n.row][n.column].value); 233 return cells[n.row][n.column].value; 234 } 235 } 236 237 //System.out.println("=>" + val); 238 return val; 239 } 240 241 @Override 242 public synchronized void paint(Graphics g) { 243 int i, j; 244 int cx, cy; 245 char l[] = new char[1]; 246 247 248 Dimension d = getSize(); 249 250 g.setFont(titleFont); 251 i = g.getFontMetrics().stringWidth(title); 252 g.drawString((title == null) ? "Spreadsheet" : title, 253 (d.width - i) / 2, 12); 254 g.setColor(inputColor); 255 g.fillRect(0, cellHeight, d.width, cellHeight); 256 g.setFont(titleFont); 257 for (i = 0; i < rows + 1; i++) { 258 cy = (i + 2) * cellHeight; 259 g.setColor(getBackground()); 260 g.draw3DRect(0, cy, d.width, 2, true); 261 if (i < rows) { 262 g.setColor(Color.red); 263 g.drawString("" + (i + 1), 2, cy + 12); 264 } 265 } 266 267 g.setColor(Color.red); 268 cy = (rows + 3) * cellHeight + (cellHeight / 2); 269 for (i = 0; i < columns; i++) { 270 cx = i * cellWidth; 271 g.setColor(getBackground()); 272 g.draw3DRect(cx + rowLabelWidth, 273 2 * cellHeight, 1, d.height, true); 274 if (i < columns) { 275 g.setColor(Color.red); 276 l[0] = (char) ((int) 'A' + i); 277 g.drawString(new String(l), 278 cx + rowLabelWidth + (cellWidth / 2), 279 cy); 280 } 281 } 282 283 for (i = 0; i < rows; i++) { 284 for (j = 0; j < columns; j++) { 285 cx = (j * cellWidth) + 2 + rowLabelWidth; 286 cy = ((i + 1) * cellHeight) + 2 + titleHeight; 287 if (cells[i][j] != null) { 288 cells[i][j].paint(g, cx, cy); 289 } 290 } 291 } 292 293 g.setColor(getBackground()); 294 g.draw3DRect(0, titleHeight, 295 d.width, 296 d.height - titleHeight, 297 false); 298 inputArea.paint(g, 1, titleHeight + 1); 299 } 300 301 //1.1 event handling 302 @Override 303 public void mouseClicked(MouseEvent e) { 304 } 305 306 @Override 307 public void mousePressed(MouseEvent e) { 308 int x = e.getX(); 309 int y = e.getY(); 310 Cell cell; 311 if (y < (titleHeight + cellHeight)) { 312 selectedRow = -1; 313 if (y <= titleHeight && current != null) { 314 current.deselect(); 315 current = null; 316 } 317 e.consume(); 318 } 319 if (x < rowLabelWidth) { 320 selectedRow = -1; 321 if (current != null) { 322 current.deselect(); 323 current = null; 324 } 325 e.consume(); 326 327 } 328 selectedRow = ((y - cellHeight - titleHeight) / cellHeight); 329 selectedColumn = (x - rowLabelWidth) / cellWidth; 330 if (selectedRow > rows 331 || selectedColumn >= columns) { 332 selectedRow = -1; 333 if (current != null) { 334 current.deselect(); 335 current = null; 336 } 337 } else { 338 if (selectedRow >= rows) { 339 selectedRow = -1; 340 if (current != null) { 341 current.deselect(); 342 current = null; 343 } 344 e.consume(); 345 } 346 if (selectedRow != -1) { 347 cell = cells[selectedRow][selectedColumn]; 348 inputArea.setText(cell.getPrintString()); 349 if (current != null) { 350 current.deselect(); 351 } 352 current = cell; 353 current.select(); 354 requestFocus(); 355 fullUpdate = true; 356 repaint(); 357 } 358 e.consume(); 359 } 360 } 361 362 @Override 363 public void mouseReleased(MouseEvent e) { 364 } 365 366 @Override 367 public void mouseEntered(MouseEvent e) { 368 } 369 370 @Override 371 public void mouseExited(MouseEvent e) { 372 } 373 374 @Override 375 public void keyPressed(KeyEvent e) { 376 } 377 378 @Override 379 public void keyTyped(KeyEvent e) { 380 fullUpdate = true; 381 inputArea.processKey(e); 382 e.consume(); 383 } 384 385 @Override 386 public void keyReleased(KeyEvent e) { 387 } 388 389 @Override 390 public String getAppletInfo() { 391 return "Title: SpreadSheet \nAuthor: Sami Shaio \nA simple spread sheet."; 392 } 393 394 @Override 395 public String[][] getParameterInfo() { 396 String[][] info = { 397 { "title", "string", 398 "The title of the spread sheet. Default is 'Spreadsheet'" }, 399 { "rows", "int", "The number of rows. Default is 9." }, 400 { "columns", "int", "The number of columns. Default is 5." } 401 }; 402 return info; 403 } 404} 405 406 407class CellUpdater extends Thread { 408 409 Cell target; 410 InputStream dataStream = null; 411 StreamTokenizer tokenStream; 412 public volatile boolean run = true; 413 414 public CellUpdater(Cell c) { 415 super("cell updater"); 416 target = c; 417 } 418 419 @Override 420 public void run() { 421 try { 422 dataStream = new URL(target.app.getDocumentBase(), 423 target.getValueString()).openStream(); 424 tokenStream = new StreamTokenizer(new BufferedReader( 425 new InputStreamReader(dataStream))); 426 tokenStream.eolIsSignificant(false); 427 428 while (run) { 429 switch (tokenStream.nextToken()) { 430 case StreamTokenizer.TT_EOF: 431 dataStream.close(); 432 return; 433 default: 434 break; 435 case StreamTokenizer.TT_NUMBER: 436 target.setTransientValue((float) tokenStream.nval); 437 if (!target.app.isStopped && !target.paused) { 438 target.app.repaint(); 439 } 440 break; 441 } 442 try { 443 Thread.sleep(2000); 444 } catch (InterruptedException e) { 445 break; 446 } 447 } 448 } catch (IOException e) { 449 return; 450 } 451 } 452} 453 454 455class Cell { 456 457 public static final int VALUE = 0; 458 public static final int LABEL = 1; 459 public static final int URL = 2; 460 public static final int FORMULA = 3; 461 Node parseRoot; 462 boolean needRedisplay; 463 boolean selected = false; 464 boolean transientValue = false; 465 public int type = Cell.VALUE; 466 String valueString = ""; 467 String printString = "v"; 468 float value; 469 Color bgColor; 470 Color fgColor; 471 Color highlightColor; 472 int width; 473 int height; 474 SpreadSheet app; 475 CellUpdater updaterThread; 476 boolean paused = false; 477 478 public Cell(SpreadSheet app, 479 Color bgColor, 480 Color fgColor, 481 Color highlightColor, 482 int width, 483 int height) { 484 this.app = app; 485 this.bgColor = bgColor; 486 this.fgColor = fgColor; 487 this.highlightColor = highlightColor; 488 this.width = width; 489 this.height = height; 490 needRedisplay = true; 491 } 492 493 public void setRawValue(float f) { 494 valueString = Float.toString(f); 495 value = f; 496 } 497 498 public void setValue(float f) { 499 setRawValue(f); 500 printString = "v" + valueString; 501 type = Cell.VALUE; 502 paused = false; 503 app.recalculate(); 504 needRedisplay = true; 505 } 506 507 public void setTransientValue(float f) { 508 transientValue = true; 509 value = f; 510 needRedisplay = true; 511 app.recalculate(); 512 } 513 514 public void setUnparsedValue(String s) { 515 switch (s.charAt(0)) { 516 case 'v': 517 setValue(Cell.VALUE, s.substring(1)); 518 break; 519 case 'f': 520 setValue(Cell.FORMULA, s.substring(1)); 521 break; 522 case 'l': 523 setValue(Cell.LABEL, s.substring(1)); 524 break; 525 case 'u': 526 setValue(Cell.URL, s.substring(1)); 527 break; 528 } 529 } 530 531 /** 532 * Parse a spreadsheet formula. The syntax is defined as: 533 * 534 * formula -> value 535 * formula -> value op value 536 * value -> '(' formula ')' 537 * value -> cell 538 * value -> <number> 539 * op -> '+' | '*' | '/' | '-' 540 * cell -> <letter><number> 541 */ 542 public String parseFormula(String formula, Node node) { 543 String subformula; 544 String restFormula; 545 Node left; 546 Node right; 547 char op; 548 549 if (formula == null) { 550 return null; 551 } 552 subformula = parseValue(formula, node); 553 //System.out.println("subformula = " + subformula); 554 if (subformula == null || subformula.length() == 0) { 555 //System.out.println("Parse succeeded"); 556 return null; 557 } 558 if (subformula.equals(formula)) { 559 //System.out.println("Parse failed"); 560 return formula; 561 } 562 563 // parse an operator and then another value 564 switch (op = subformula.charAt(0)) { 565 case 0: 566 //System.out.println("Parse succeeded"); 567 return null; 568 case ')': 569 //System.out.println("Returning subformula=" + subformula); 570 return subformula; 571 case '+': 572 case '*': 573 case '-': 574 case '/': 575 restFormula = subformula.substring(1); 576 subformula = parseValue(restFormula, right = new Node()); 577 //System.out.println("subformula(2) = " + subformula); 578 if (subformula == null ? restFormula != null : !subformula. 579 equals(restFormula)) { 580 //System.out.println("Parse succeeded"); 581 left = new Node(node); 582 node.left = left; 583 node.right = right; 584 node.op = op; 585 node.type = Node.OP; 586 //node.print(3); 587 return subformula; 588 } else { 589 //System.out.println("Parse failed"); 590 return formula; 591 } 592 default: 593 //System.out.println("Parse failed (bad operator): " + subformula); 594 return formula; 595 } 596 } 597 598 public String parseValue(String formula, Node node) { 599 char c = formula.charAt(0); 600 String subformula; 601 String restFormula; 602 float _value; 603 int row; 604 int column; 605 606 //System.out.println("parseValue: " + formula); 607 restFormula = formula; 608 if (c == '(') { 609 //System.out.println("parseValue(" + formula + ")"); 610 restFormula = formula.substring(1); 611 subformula = parseFormula(restFormula, node); 612 //System.out.println("rest=(" + subformula + ")"); 613 if (subformula == null 614 || subformula.length() == restFormula.length()) { 615 //System.out.println("Failed"); 616 return formula; 617 } else if (!(subformula.charAt(0) == ')')) { 618 //System.out.println("Failed (missing parentheses)"); 619 return formula; 620 } 621 restFormula = subformula; 622 } else if (c >= '0' && c <= '9') { 623 int i; 624 625 //System.out.println("formula=" + formula); 626 for (i = 0; i < formula.length(); i++) { 627 c = formula.charAt(i); 628 if ((c < '0' || c > '9') && c != '.') { 629 break; 630 } 631 } 632 try { 633 _value = Float.valueOf(formula.substring(0, i)).floatValue(); 634 } catch (NumberFormatException e) { 635 //System.out.println("Failed (number format error)"); 636 return formula; 637 } 638 node.type = Node.VALUE; 639 node.value = _value; 640 //node.print(3); 641 restFormula = formula.substring(i); 642 //System.out.println("value= " + value + " i=" + i + 643 // " rest = " + restFormula); 644 return restFormula; 645 } else if (c >= 'A' && c <= 'Z') { 646 int i; 647 648 column = c - 'A'; 649 restFormula = formula.substring(1); 650 for (i = 0; i < restFormula.length(); i++) { 651 c = restFormula.charAt(i); 652 if (c < '0' || c > '9') { 653 break; 654 } 655 } 656 row = Float.valueOf(restFormula.substring(0, i)).intValue(); 657 //System.out.println("row = " + row + " column = " + column); 658 node.row = row - 1; 659 node.column = column; 660 node.type = Node.CELL; 661 //node.print(3); 662 if (i == restFormula.length()) { 663 restFormula = null; 664 } else { 665 restFormula = restFormula.substring(i); 666 if (restFormula.charAt(0) == 0) { 667 return null; 668 } 669 } 670 } 671 672 return restFormula; 673 } 674 675 public void setValue(int type, String s) { 676 paused = false; 677 if (this.type == Cell.URL) { 678 updaterThread.run = false; 679 updaterThread = null; 680 } 681 682 valueString = s; 683 this.type = type; 684 needRedisplay = true; 685 switch (type) { 686 case Cell.VALUE: 687 setValue(Float.valueOf(s).floatValue()); 688 break; 689 case Cell.LABEL: 690 printString = "l" + valueString; 691 break; 692 case Cell.URL: 693 printString = "u" + valueString; 694 updaterThread = new CellUpdater(this); 695 updaterThread.start(); 696 break; 697 case Cell.FORMULA: 698 parseFormula(valueString, parseRoot = new Node()); 699 printString = "f" + valueString; 700 break; 701 } 702 app.recalculate(); 703 } 704 705 public String getValueString() { 706 return valueString; 707 } 708 709 public String getPrintString() { 710 return printString; 711 } 712 713 public void select() { 714 selected = true; 715 paused = true; 716 } 717 718 public void deselect() { 719 selected = false; 720 paused = false; 721 needRedisplay = true; 722 app.repaint(); 723 } 724 725 public void paint(Graphics g, int x, int y) { 726 if (selected) { 727 g.setColor(highlightColor); 728 } else { 729 g.setColor(bgColor); 730 } 731 g.fillRect(x, y, width - 1, height); 732 if (valueString != null) { 733 switch (type) { 734 case Cell.VALUE: 735 case Cell.LABEL: 736 g.setColor(fgColor); 737 break; 738 case Cell.FORMULA: 739 g.setColor(Color.red); 740 break; 741 case Cell.URL: 742 g.setColor(Color.blue); 743 break; 744 } 745 if (transientValue) { 746 g.drawString("" + value, x, y + (height / 2) + 5); 747 } else { 748 if (valueString.length() > 14) { 749 g.drawString(valueString.substring(0, 14), 750 x, y + (height / 2) + 5); 751 } else { 752 g.drawString(valueString, x, y + (height / 2) + 5); 753 } 754 } 755 } 756 needRedisplay = false; 757 } 758} 759 760 761class Node { 762 763 public static final int OP = 0; 764 public static final int VALUE = 1; 765 public static final int CELL = 2; 766 int type; 767 Node left; 768 Node right; 769 int row; 770 int column; 771 float value; 772 char op; 773 774 public Node() { 775 left = null; 776 right = null; 777 value = 0; 778 row = -1; 779 column = -1; 780 op = 0; 781 type = Node.VALUE; 782 } 783 784 public Node(Node n) { 785 left = n.left; 786 right = n.right; 787 value = n.value; 788 row = n.row; 789 column = n.column; 790 op = n.op; 791 type = n.type; 792 } 793 794 public void indent(int ind) { 795 for (int i = 0; i < ind; i++) { 796 System.out.print(" "); 797 } 798 } 799 800 public void print(int indentLevel) { 801 char l[] = new char[1]; 802 indent(indentLevel); 803 System.out.println("NODE type=" + type); 804 indent(indentLevel); 805 switch (type) { 806 case Node.VALUE: 807 System.out.println(" value=" + value); 808 break; 809 case Node.CELL: 810 l[0] = (char) ((int) 'A' + column); 811 System.out.println(" cell=" + new String(l) + (row + 1)); 812 break; 813 case Node.OP: 814 System.out.println(" op=" + op); 815 left.print(indentLevel + 3); 816 right.print(indentLevel + 3); 817 break; 818 } 819 } 820} 821 822 823class InputField { 824 825 int maxchars = 50; 826 int cursorPos = 0; 827 Applet app; 828 String sval; 829 char buffer[]; 830 int nChars; 831 int width; 832 int height; 833 Color bgColor; 834 Color fgColor; 835 836 public InputField(String initValue, Applet app, int width, int height, 837 Color bgColor, Color fgColor) { 838 this.width = width; 839 this.height = height; 840 this.bgColor = bgColor; 841 this.fgColor = fgColor; 842 this.app = app; 843 buffer = new char[maxchars]; 844 nChars = 0; 845 if (initValue != null) { 846 initValue.getChars(0, initValue.length(), this.buffer, 0); 847 nChars = initValue.length(); 848 } 849 sval = initValue; 850 } 851 852 public void setText(String val) { 853 int i; 854 855 for (i = 0; i < maxchars; i++) { 856 buffer[i] = 0; 857 } 858 if (val == null) { 859 sval = ""; 860 } else { 861 sval = val; 862 } 863 nChars = sval.length(); 864 sval.getChars(0, sval.length(), buffer, 0); 865 } 866 867 public String getValue() { 868 return sval; 869 } 870 871 public void paint(Graphics g, int x, int y) { 872 g.setColor(bgColor); 873 g.fillRect(x, y, width, height); 874 if (sval != null) { 875 g.setColor(fgColor); 876 g.drawString(sval, x, y + (height / 2) + 3); 877 } 878 } 879 880 public void processKey(KeyEvent e) { 881 char ch = e.getKeyChar(); 882 switch (ch) { 883 case '\b': // delete 884 if (nChars > 0) { 885 nChars--; 886 sval = new String(buffer, 0, nChars); 887 } 888 break; 889 case '\n': // return 890 selected(); 891 break; 892 default: 893 if (nChars < maxchars && ch >= '0') { 894 buffer[nChars++] = ch; 895 sval = new String(buffer, 0, nChars); 896 } 897 } 898 app.repaint(); 899 } 900 901 public void keyReleased(KeyEvent e) { 902 } 903 904 public void selected() { 905 } 906} 907 908 909class SpreadSheetInput 910 extends InputField { 911 912 public SpreadSheetInput(String initValue, 913 SpreadSheet app, 914 int width, 915 int height, 916 Color bgColor, 917 Color fgColor) { 918 super(initValue, app, width, height, bgColor, fgColor); 919 } 920 921 @Override 922 public void selected() { 923 float f; 924 sval = ("".equals(sval)) ? "v" : sval; 925 switch (sval.charAt(0)) { 926 case 'v': 927 String s = sval.substring(1); 928 try { 929 int i; 930 for (i = 0; i < s.length(); i++) { 931 char c = s.charAt(i); 932 if (c < '0' || c > '9') { 933 break; 934 } 935 } 936 s = s.substring(0, i); 937 f = Float.valueOf(s).floatValue(); 938 ((SpreadSheet) app).setCurrentValue(f); 939 } catch (NumberFormatException e) { 940 System.out.println("Not a float: '" + s + "'"); 941 } 942 break; 943 case 'l': 944 ((SpreadSheet) app).setCurrentValue(Cell.LABEL, 945 sval.substring(1)); 946 break; 947 case 'u': 948 ((SpreadSheet) app).setCurrentValue(Cell.URL, sval.substring(1)); 949 break; 950 case 'f': 951 ((SpreadSheet) app).setCurrentValue(Cell.FORMULA, 952 sval.substring(1)); 953 break; 954 } 955 } 956} 957