0N/A/*
3852N/A * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
0N/A *
0N/A * Redistribution and use in source and binary forms, with or without
0N/A * modification, are permitted provided that the following conditions
0N/A * are met:
0N/A *
0N/A * - Redistributions of source code must retain the above copyright
0N/A * notice, this list of conditions and the following disclaimer.
0N/A *
0N/A * - Redistributions in binary form must reproduce the above copyright
0N/A * notice, this list of conditions and the following disclaimer in the
0N/A * documentation and/or other materials provided with the distribution.
0N/A *
2362N/A * - Neither the name of Oracle nor the names of its
0N/A * contributors may be used to endorse or promote products derived
0N/A * from this software without specific prior written permission.
0N/A *
0N/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
0N/A * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
0N/A * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
0N/A * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
0N/A * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0N/A * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0N/A * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
0N/A * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
0N/A * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
0N/A * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0N/A * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0N/A */
0N/A
4378N/A/*
4378N/A * This source code is provided to illustrate the usage of a given feature
4378N/A * or technique and has been deliberately simplified. Additional steps
4378N/A * required for a production-quality application, such as security checks,
4378N/A * input validation and proper error handling, might not be present in
4378N/A * this sample code.
4378N/A */
4378N/A
4378N/A
0N/A
0N/Aimport java.applet.Applet;
0N/Aimport java.awt.*;
0N/Aimport java.awt.event.*;
0N/Aimport java.io.*;
0N/Aimport java.net.*;
0N/A
3852N/A
3852N/A@SuppressWarnings("serial")
3852N/Apublic class SpreadSheet extends Applet implements MouseListener, KeyListener {
0N/A
3852N/A String title;
3852N/A Font titleFont;
3852N/A Color cellColor;
3852N/A Color inputColor;
3852N/A int cellWidth = 100;
3852N/A int cellHeight = 15;
3852N/A int titleHeight = 15;
3852N/A int rowLabelWidth = 15;
3852N/A Font inputFont;
3852N/A boolean isStopped = false;
3852N/A boolean fullUpdate = true;
3852N/A int rows;
3852N/A int columns;
3852N/A int currentKey = -1;
3852N/A int selectedRow = -1;
3852N/A int selectedColumn = -1;
3852N/A SpreadSheetInput inputArea;
3852N/A Cell cells[][];
3852N/A Cell current = null;
3852N/A
3852N/A @Override
0N/A public synchronized void init() {
0N/A String rs;
0N/A
0N/A cellColor = Color.white;
0N/A inputColor = new Color(100, 100, 225);
0N/A inputFont = new Font("Monospaced", Font.PLAIN, 10);
0N/A titleFont = new Font("Monospaced", Font.BOLD, 12);
0N/A title = getParameter("title");
0N/A if (title == null) {
0N/A title = "Spreadsheet";
0N/A }
0N/A rs = getParameter("rows");
0N/A if (rs == null) {
0N/A rows = 9;
0N/A } else {
0N/A rows = Integer.parseInt(rs);
0N/A }
0N/A rs = getParameter("columns");
0N/A if (rs == null) {
0N/A columns = 5;
0N/A } else {
0N/A columns = Integer.parseInt(rs);
0N/A }
0N/A cells = new Cell[rows][columns];
0N/A char l[] = new char[1];
3852N/A for (int i = 0; i < rows; i++) {
3852N/A for (int j = 0; j < columns; j++) {
0N/A
0N/A cells[i][j] = new Cell(this,
3852N/A Color.lightGray,
3852N/A Color.black,
3852N/A cellColor,
3852N/A cellWidth - 2,
3852N/A cellHeight - 2);
3852N/A l[0] = (char) ((int) 'a' + j);
3852N/A rs = getParameter("" + new String(l) + (i + 1));
0N/A if (rs != null) {
0N/A cells[i][j].setUnparsedValue(rs);
0N/A }
0N/A }
0N/A }
0N/A
0N/A Dimension d = getSize();
0N/A inputArea = new SpreadSheetInput(null, this, d.width - 2, cellHeight - 1,
3852N/A inputColor, Color.white);
0N/A resize(columns * cellWidth + rowLabelWidth,
3852N/A (rows + 3) * cellHeight + titleHeight);
0N/A addMouseListener(this);
0N/A addKeyListener(this);
0N/A }
0N/A
0N/A public void setCurrentValue(float val) {
0N/A if (selectedRow == -1 || selectedColumn == -1) {
0N/A return;
0N/A }
0N/A cells[selectedRow][selectedColumn].setValue(val);
0N/A repaint();
0N/A }
0N/A
3852N/A @Override
0N/A public void stop() {
0N/A isStopped = true;
0N/A }
0N/A
3852N/A @Override
0N/A public void start() {
0N/A isStopped = false;
0N/A }
0N/A
3852N/A @Override
0N/A public void destroy() {
3852N/A for (int i = 0; i < rows; i++) {
3852N/A for (int j = 0; j < columns; j++) {
0N/A if (cells[i][j].type == Cell.URL) {
3852N/A cells[i][j].updaterThread.run = false;
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
0N/A public void setCurrentValue(int type, String val) {
0N/A if (selectedRow == -1 || selectedColumn == -1) {
0N/A return;
0N/A }
0N/A cells[selectedRow][selectedColumn].setValue(type, val);
0N/A repaint();
0N/A }
0N/A
3852N/A @Override
0N/A public void update(Graphics g) {
3852N/A if (!fullUpdate) {
0N/A int cx, cy;
0N/A
0N/A g.setFont(titleFont);
3852N/A for (int i = 0; i < rows; i++) {
3852N/A for (int j = 0; j < columns; j++) {
0N/A if (cells[i][j].needRedisplay) {
0N/A cx = (j * cellWidth) + 2 + rowLabelWidth;
3852N/A cy = ((i + 1) * cellHeight) + 2 + titleHeight;
0N/A cells[i][j].paint(g, cx, cy);
0N/A }
0N/A }
0N/A }
0N/A } else {
0N/A paint(g);
0N/A fullUpdate = false;
0N/A }
0N/A }
0N/A
0N/A public void recalculate() {
3852N/A int i, j;
0N/A
0N/A //System.out.println("SpreadSheet.recalculate");
3852N/A for (i = 0; i < rows; i++) {
3852N/A for (j = 0; j < columns; j++) {
0N/A if (cells[i][j] != null && cells[i][j].type == Cell.FORMULA) {
3852N/A cells[i][j].setRawValue(evaluateFormula(
3852N/A cells[i][j].parseRoot));
0N/A cells[i][j].needRedisplay = true;
0N/A }
0N/A }
0N/A }
0N/A repaint();
0N/A }
0N/A
3852N/A float evaluateFormula(Node n) {
3852N/A float val = 0.0f;
0N/A
0N/A //System.out.println("evaluateFormula:");
0N/A //n.print(3);
0N/A if (n == null) {
0N/A //System.out.println("Null node");
0N/A return val;
0N/A }
0N/A switch (n.type) {
3852N/A case Node.OP:
3852N/A val = evaluateFormula(n.left);
3852N/A switch (n.op) {
3852N/A case '+':
3852N/A val += evaluateFormula(n.right);
3852N/A break;
3852N/A case '*':
3852N/A val *= evaluateFormula(n.right);
3852N/A break;
3852N/A case '-':
3852N/A val -= evaluateFormula(n.right);
3852N/A break;
3852N/A case '/':
3852N/A val /= evaluateFormula(n.right);
3852N/A break;
3852N/A }
0N/A break;
3852N/A case Node.VALUE:
3852N/A //System.out.println("=>" + n.value);
3852N/A return n.value;
3852N/A case Node.CELL:
0N/A if (cells[n.row][n.column] == null) {
0N/A //System.out.println("NULL at 193");
0N/A } else {
0N/A //System.out.println("=>" + cells[n.row][n.column].value);
0N/A return cells[n.row][n.column].value;
0N/A }
0N/A }
0N/A
0N/A //System.out.println("=>" + val);
0N/A return val;
0N/A }
0N/A
3852N/A @Override
0N/A public synchronized void paint(Graphics g) {
0N/A int i, j;
0N/A int cx, cy;
0N/A char l[] = new char[1];
0N/A
0N/A
0N/A Dimension d = getSize();
0N/A
0N/A g.setFont(titleFont);
0N/A i = g.getFontMetrics().stringWidth(title);
0N/A g.drawString((title == null) ? "Spreadsheet" : title,
3852N/A (d.width - i) / 2, 12);
0N/A g.setColor(inputColor);
0N/A g.fillRect(0, cellHeight, d.width, cellHeight);
0N/A g.setFont(titleFont);
3852N/A for (i = 0; i < rows + 1; i++) {
3852N/A cy = (i + 2) * cellHeight;
0N/A g.setColor(getBackground());
0N/A g.draw3DRect(0, cy, d.width, 2, true);
0N/A if (i < rows) {
0N/A g.setColor(Color.red);
3852N/A g.drawString("" + (i + 1), 2, cy + 12);
0N/A }
0N/A }
0N/A
0N/A g.setColor(Color.red);
3852N/A cy = (rows + 3) * cellHeight + (cellHeight / 2);
3852N/A for (i = 0; i < columns; i++) {
0N/A cx = i * cellWidth;
0N/A g.setColor(getBackground());
0N/A g.draw3DRect(cx + rowLabelWidth,
3852N/A 2 * cellHeight, 1, d.height, true);
0N/A if (i < columns) {
0N/A g.setColor(Color.red);
3852N/A l[0] = (char) ((int) 'A' + i);
0N/A g.drawString(new String(l),
3852N/A cx + rowLabelWidth + (cellWidth / 2),
3852N/A cy);
0N/A }
0N/A }
0N/A
3852N/A for (i = 0; i < rows; i++) {
3852N/A for (j = 0; j < columns; j++) {
0N/A cx = (j * cellWidth) + 2 + rowLabelWidth;
3852N/A cy = ((i + 1) * cellHeight) + 2 + titleHeight;
0N/A if (cells[i][j] != null) {
0N/A cells[i][j].paint(g, cx, cy);
0N/A }
0N/A }
0N/A }
0N/A
0N/A g.setColor(getBackground());
0N/A g.draw3DRect(0, titleHeight,
3852N/A d.width,
3852N/A d.height - titleHeight,
3852N/A false);
0N/A inputArea.paint(g, 1, titleHeight + 1);
0N/A }
0N/A
3852N/A //1.1 event handling
3852N/A @Override
3852N/A public void mouseClicked(MouseEvent e) {
0N/A }
3852N/A
3852N/A @Override
3852N/A public void mousePressed(MouseEvent e) {
3852N/A int x = e.getX();
3852N/A int y = e.getY();
3852N/A Cell cell;
3852N/A if (y < (titleHeight + cellHeight)) {
3852N/A selectedRow = -1;
3852N/A if (y <= titleHeight && current != null) {
3852N/A current.deselect();
3852N/A current = null;
3852N/A }
3852N/A e.consume();
3852N/A }
3852N/A if (x < rowLabelWidth) {
3852N/A selectedRow = -1;
3852N/A if (current != null) {
3852N/A current.deselect();
0N/A current = null;
3852N/A }
3852N/A e.consume();
0N/A
3852N/A }
3852N/A selectedRow = ((y - cellHeight - titleHeight) / cellHeight);
3852N/A selectedColumn = (x - rowLabelWidth) / cellWidth;
3852N/A if (selectedRow > rows
3852N/A || selectedColumn >= columns) {
3852N/A selectedRow = -1;
3852N/A if (current != null) {
3852N/A current.deselect();
3852N/A current = null;
3852N/A }
3852N/A } else {
3852N/A if (selectedRow >= rows) {
3852N/A selectedRow = -1;
3852N/A if (current != null) {
3852N/A current.deselect();
3852N/A current = null;
3852N/A }
3852N/A e.consume();
3852N/A }
3852N/A if (selectedRow != -1) {
3852N/A cell = cells[selectedRow][selectedColumn];
3852N/A inputArea.setText(cell.getPrintString());
3852N/A if (current != null) {
3852N/A current.deselect();
3852N/A }
3852N/A current = cell;
3852N/A current.select();
3852N/A requestFocus();
3852N/A fullUpdate = true;
3852N/A repaint();
3852N/A }
3852N/A e.consume();
3852N/A }
0N/A }
3852N/A
3852N/A @Override
3852N/A public void mouseReleased(MouseEvent e) {
3852N/A }
3852N/A
3852N/A @Override
3852N/A public void mouseEntered(MouseEvent e) {
3852N/A }
3852N/A
3852N/A @Override
3852N/A public void mouseExited(MouseEvent e) {
3852N/A }
3852N/A
3852N/A @Override
3852N/A public void keyPressed(KeyEvent e) {
3852N/A }
3852N/A
3852N/A @Override
3852N/A public void keyTyped(KeyEvent e) {
3852N/A fullUpdate = true;
3852N/A inputArea.processKey(e);
0N/A e.consume();
3852N/A }
3852N/A
3852N/A @Override
3852N/A public void keyReleased(KeyEvent e) {
0N/A }
0N/A
3852N/A @Override
3852N/A public String getAppletInfo() {
3852N/A return "Title: SpreadSheet \nAuthor: Sami Shaio \nA simple spread sheet.";
3852N/A }
0N/A
3852N/A @Override
3852N/A public String[][] getParameterInfo() {
3852N/A String[][] info = {
3852N/A { "title", "string",
3852N/A "The title of the spread sheet. Default is 'Spreadsheet'" },
3852N/A { "rows", "int", "The number of rows. Default is 9." },
3852N/A { "columns", "int", "The number of columns. Default is 5." }
3852N/A };
3852N/A return info;
3852N/A }
3852N/A}
0N/A
0N/A
3852N/Aclass CellUpdater extends Thread {
0N/A
3852N/A Cell target;
0N/A InputStream dataStream = null;
0N/A StreamTokenizer tokenStream;
3852N/A public volatile boolean run = true;
0N/A
0N/A public CellUpdater(Cell c) {
0N/A super("cell updater");
0N/A target = c;
0N/A }
0N/A
3852N/A @Override
0N/A public void run() {
0N/A try {
0N/A dataStream = new URL(target.app.getDocumentBase(),
3852N/A target.getValueString()).openStream();
3852N/A tokenStream = new StreamTokenizer(new BufferedReader(
3852N/A new InputStreamReader(dataStream)));
0N/A tokenStream.eolIsSignificant(false);
0N/A
3852N/A while (run) {
0N/A switch (tokenStream.nextToken()) {
3852N/A case StreamTokenizer.TT_EOF:
3852N/A dataStream.close();
3852N/A return;
3852N/A default:
3852N/A break;
3852N/A case StreamTokenizer.TT_NUMBER:
3852N/A target.setTransientValue((float) tokenStream.nval);
3852N/A if (!target.app.isStopped && !target.paused) {
3852N/A target.app.repaint();
3852N/A }
3852N/A break;
0N/A }
0N/A try {
0N/A Thread.sleep(2000);
0N/A } catch (InterruptedException e) {
0N/A break;
0N/A }
0N/A }
0N/A } catch (IOException e) {
0N/A return;
0N/A }
0N/A }
0N/A}
0N/A
3852N/A
0N/Aclass Cell {
3852N/A
0N/A public static final int VALUE = 0;
0N/A public static final int LABEL = 1;
3852N/A public static final int URL = 2;
0N/A public static final int FORMULA = 3;
3852N/A Node parseRoot;
3852N/A boolean needRedisplay;
0N/A boolean selected = false;
0N/A boolean transientValue = false;
3852N/A public int type = Cell.VALUE;
3852N/A String valueString = "";
3852N/A String printString = "v";
3852N/A float value;
3852N/A Color bgColor;
3852N/A Color fgColor;
3852N/A Color highlightColor;
3852N/A int width;
3852N/A int height;
0N/A SpreadSheet app;
0N/A CellUpdater updaterThread;
3852N/A boolean paused = false;
0N/A
0N/A public Cell(SpreadSheet app,
3852N/A Color bgColor,
3852N/A Color fgColor,
3852N/A Color highlightColor,
3852N/A int width,
3852N/A int height) {
0N/A this.app = app;
0N/A this.bgColor = bgColor;
0N/A this.fgColor = fgColor;
0N/A this.highlightColor = highlightColor;
0N/A this.width = width;
0N/A this.height = height;
0N/A needRedisplay = true;
0N/A }
0N/A
0N/A public void setRawValue(float f) {
0N/A valueString = Float.toString(f);
0N/A value = f;
0N/A }
3852N/A
0N/A public void setValue(float f) {
0N/A setRawValue(f);
0N/A printString = "v" + valueString;
0N/A type = Cell.VALUE;
0N/A paused = false;
0N/A app.recalculate();
0N/A needRedisplay = true;
0N/A }
0N/A
0N/A public void setTransientValue(float f) {
0N/A transientValue = true;
0N/A value = f;
0N/A needRedisplay = true;
0N/A app.recalculate();
0N/A }
0N/A
0N/A public void setUnparsedValue(String s) {
0N/A switch (s.charAt(0)) {
3852N/A case 'v':
3852N/A setValue(Cell.VALUE, s.substring(1));
3852N/A break;
3852N/A case 'f':
3852N/A setValue(Cell.FORMULA, s.substring(1));
3852N/A break;
3852N/A case 'l':
3852N/A setValue(Cell.LABEL, s.substring(1));
3852N/A break;
3852N/A case 'u':
3852N/A setValue(Cell.URL, s.substring(1));
3852N/A break;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Parse a spreadsheet formula. The syntax is defined as:
0N/A *
0N/A * formula -> value
0N/A * formula -> value op value
0N/A * value -> '(' formula ')'
0N/A * value -> cell
0N/A * value -> <number>
0N/A * op -> '+' | '*' | '/' | '-'
0N/A * cell -> <letter><number>
0N/A */
0N/A public String parseFormula(String formula, Node node) {
0N/A String subformula;
0N/A String restFormula;
0N/A Node left;
0N/A Node right;
0N/A char op;
0N/A
0N/A if (formula == null) {
0N/A return null;
0N/A }
0N/A subformula = parseValue(formula, node);
0N/A //System.out.println("subformula = " + subformula);
0N/A if (subformula == null || subformula.length() == 0) {
0N/A //System.out.println("Parse succeeded");
0N/A return null;
0N/A }
3852N/A if (subformula.equals(formula)) {
0N/A //System.out.println("Parse failed");
0N/A return formula;
0N/A }
0N/A
0N/A // parse an operator and then another value
0N/A switch (op = subformula.charAt(0)) {
3852N/A case 0:
0N/A //System.out.println("Parse succeeded");
3852N/A return null;
3852N/A case ')':
3852N/A //System.out.println("Returning subformula=" + subformula);
0N/A return subformula;
3852N/A case '+':
3852N/A case '*':
3852N/A case '-':
3852N/A case '/':
3852N/A restFormula = subformula.substring(1);
3852N/A subformula = parseValue(restFormula, right = new Node());
3852N/A //System.out.println("subformula(2) = " + subformula);
3852N/A if (subformula == null ? restFormula != null : !subformula.
3852N/A equals(restFormula)) {
3852N/A //System.out.println("Parse succeeded");
3852N/A left = new Node(node);
3852N/A node.left = left;
3852N/A node.right = right;
3852N/A node.op = op;
3852N/A node.type = Node.OP;
3852N/A //node.print(3);
3852N/A return subformula;
3852N/A } else {
3852N/A //System.out.println("Parse failed");
3852N/A return formula;
3852N/A }
3852N/A default:
3852N/A //System.out.println("Parse failed (bad operator): " + subformula);
0N/A return formula;
0N/A }
0N/A }
0N/A
0N/A public String parseValue(String formula, Node node) {
3852N/A char c = formula.charAt(0);
3852N/A String subformula;
3852N/A String restFormula;
3852N/A float _value;
3852N/A int row;
3852N/A int column;
0N/A
0N/A //System.out.println("parseValue: " + formula);
0N/A restFormula = formula;
0N/A if (c == '(') {
0N/A //System.out.println("parseValue(" + formula + ")");
0N/A restFormula = formula.substring(1);
0N/A subformula = parseFormula(restFormula, node);
0N/A //System.out.println("rest=(" + subformula + ")");
3852N/A if (subformula == null
3852N/A || subformula.length() == restFormula.length()) {
0N/A //System.out.println("Failed");
0N/A return formula;
3852N/A } else if (!(subformula.charAt(0) == ')')) {
0N/A //System.out.println("Failed (missing parentheses)");
0N/A return formula;
0N/A }
0N/A restFormula = subformula;
0N/A } else if (c >= '0' && c <= '9') {
0N/A int i;
0N/A
0N/A //System.out.println("formula=" + formula);
3852N/A for (i = 0; i < formula.length(); i++) {
0N/A c = formula.charAt(i);
0N/A if ((c < '0' || c > '9') && c != '.') {
0N/A break;
0N/A }
0N/A }
0N/A try {
3852N/A _value = Float.valueOf(formula.substring(0, i)).floatValue();
0N/A } catch (NumberFormatException e) {
0N/A //System.out.println("Failed (number format error)");
0N/A return formula;
0N/A }
0N/A node.type = Node.VALUE;
3852N/A node.value = _value;
0N/A //node.print(3);
0N/A restFormula = formula.substring(i);
0N/A //System.out.println("value= " + value + " i=" + i +
3852N/A // " rest = " + restFormula);
0N/A return restFormula;
0N/A } else if (c >= 'A' && c <= 'Z') {
0N/A int i;
0N/A
0N/A column = c - 'A';
0N/A restFormula = formula.substring(1);
3852N/A for (i = 0; i < restFormula.length(); i++) {
0N/A c = restFormula.charAt(i);
0N/A if (c < '0' || c > '9') {
0N/A break;
0N/A }
0N/A }
0N/A row = Float.valueOf(restFormula.substring(0, i)).intValue();
0N/A //System.out.println("row = " + row + " column = " + column);
0N/A node.row = row - 1;
0N/A node.column = column;
0N/A node.type = Node.CELL;
0N/A //node.print(3);
0N/A if (i == restFormula.length()) {
0N/A restFormula = null;
0N/A } else {
0N/A restFormula = restFormula.substring(i);
0N/A if (restFormula.charAt(0) == 0) {
0N/A return null;
0N/A }
0N/A }
0N/A }
0N/A
0N/A return restFormula;
0N/A }
0N/A
0N/A public void setValue(int type, String s) {
0N/A paused = false;
0N/A if (this.type == Cell.URL) {
3852N/A updaterThread.run = false;
0N/A updaterThread = null;
0N/A }
0N/A
3852N/A valueString = s;
0N/A this.type = type;
0N/A needRedisplay = true;
0N/A switch (type) {
3852N/A case Cell.VALUE:
3852N/A setValue(Float.valueOf(s).floatValue());
3852N/A break;
3852N/A case Cell.LABEL:
3852N/A printString = "l" + valueString;
3852N/A break;
3852N/A case Cell.URL:
3852N/A printString = "u" + valueString;
3852N/A updaterThread = new CellUpdater(this);
3852N/A updaterThread.start();
3852N/A break;
3852N/A case Cell.FORMULA:
3852N/A parseFormula(valueString, parseRoot = new Node());
3852N/A printString = "f" + valueString;
3852N/A break;
0N/A }
0N/A app.recalculate();
0N/A }
0N/A
0N/A public String getValueString() {
0N/A return valueString;
0N/A }
0N/A
0N/A public String getPrintString() {
0N/A return printString;
0N/A }
0N/A
0N/A public void select() {
0N/A selected = true;
0N/A paused = true;
0N/A }
3852N/A
0N/A public void deselect() {
0N/A selected = false;
0N/A paused = false;
0N/A needRedisplay = true;
0N/A app.repaint();
0N/A }
3852N/A
0N/A public void paint(Graphics g, int x, int y) {
0N/A if (selected) {
0N/A g.setColor(highlightColor);
0N/A } else {
0N/A g.setColor(bgColor);
0N/A }
0N/A g.fillRect(x, y, width - 1, height);
0N/A if (valueString != null) {
0N/A switch (type) {
3852N/A case Cell.VALUE:
3852N/A case Cell.LABEL:
3852N/A g.setColor(fgColor);
3852N/A break;
3852N/A case Cell.FORMULA:
3852N/A g.setColor(Color.red);
3852N/A break;
3852N/A case Cell.URL:
3852N/A g.setColor(Color.blue);
3852N/A break;
0N/A }
3852N/A if (transientValue) {
0N/A g.drawString("" + value, x, y + (height / 2) + 5);
0N/A } else {
0N/A if (valueString.length() > 14) {
0N/A g.drawString(valueString.substring(0, 14),
3852N/A x, y + (height / 2) + 5);
0N/A } else {
0N/A g.drawString(valueString, x, y + (height / 2) + 5);
0N/A }
0N/A }
0N/A }
0N/A needRedisplay = false;
0N/A }
0N/A}
0N/A
3852N/A
0N/Aclass Node {
3852N/A
0N/A public static final int OP = 0;
0N/A public static final int VALUE = 1;
0N/A public static final int CELL = 2;
3852N/A int type;
3852N/A Node left;
3852N/A Node right;
3852N/A int row;
3852N/A int column;
3852N/A float value;
3852N/A char op;
0N/A
0N/A public Node() {
0N/A left = null;
0N/A right = null;
0N/A value = 0;
0N/A row = -1;
0N/A column = -1;
0N/A op = 0;
0N/A type = Node.VALUE;
0N/A }
3852N/A
0N/A public Node(Node n) {
0N/A left = n.left;
0N/A right = n.right;
0N/A value = n.value;
0N/A row = n.row;
0N/A column = n.column;
0N/A op = n.op;
0N/A type = n.type;
0N/A }
3852N/A
0N/A public void indent(int ind) {
0N/A for (int i = 0; i < ind; i++) {
0N/A System.out.print(" ");
0N/A }
0N/A }
3852N/A
0N/A public void print(int indentLevel) {
0N/A char l[] = new char[1];
0N/A indent(indentLevel);
0N/A System.out.println("NODE type=" + type);
0N/A indent(indentLevel);
0N/A switch (type) {
3852N/A case Node.VALUE:
3852N/A System.out.println(" value=" + value);
3852N/A break;
3852N/A case Node.CELL:
3852N/A l[0] = (char) ((int) 'A' + column);
3852N/A System.out.println(" cell=" + new String(l) + (row + 1));
3852N/A break;
3852N/A case Node.OP:
3852N/A System.out.println(" op=" + op);
3852N/A left.print(indentLevel + 3);
3852N/A right.print(indentLevel + 3);
3852N/A break;
0N/A }
0N/A }
0N/A}
0N/A
3852N/A
0N/Aclass InputField {
3852N/A
3852N/A int maxchars = 50;
3852N/A int cursorPos = 0;
3852N/A Applet app;
3852N/A String sval;
3852N/A char buffer[];
3852N/A int nChars;
3852N/A int width;
3852N/A int height;
3852N/A Color bgColor;
3852N/A Color fgColor;
0N/A
0N/A public InputField(String initValue, Applet app, int width, int height,
3852N/A Color bgColor, Color fgColor) {
0N/A this.width = width;
0N/A this.height = height;
0N/A this.bgColor = bgColor;
0N/A this.fgColor = fgColor;
0N/A this.app = app;
0N/A buffer = new char[maxchars];
0N/A nChars = 0;
0N/A if (initValue != null) {
0N/A initValue.getChars(0, initValue.length(), this.buffer, 0);
0N/A nChars = initValue.length();
0N/A }
0N/A sval = initValue;
0N/A }
0N/A
0N/A public void setText(String val) {
0N/A int i;
0N/A
3852N/A for (i = 0; i < maxchars; i++) {
0N/A buffer[i] = 0;
0N/A }
0N/A if (val == null) {
0N/A sval = "";
0N/A } else {
0N/A sval = val;
0N/A }
0N/A nChars = sval.length();
0N/A sval.getChars(0, sval.length(), buffer, 0);
0N/A }
0N/A
0N/A public String getValue() {
0N/A return sval;
0N/A }
0N/A
0N/A public void paint(Graphics g, int x, int y) {
0N/A g.setColor(bgColor);
0N/A g.fillRect(x, y, width, height);
0N/A if (sval != null) {
0N/A g.setColor(fgColor);
0N/A g.drawString(sval, x, y + (height / 2) + 3);
0N/A }
0N/A }
0N/A
0N/A public void processKey(KeyEvent e) {
0N/A char ch = e.getKeyChar();
0N/A switch (ch) {
0N/A case '\b': // delete
0N/A if (nChars > 0) {
0N/A nChars--;
0N/A sval = new String(buffer, 0, nChars);
0N/A }
0N/A break;
0N/A case '\n': // return
0N/A selected();
0N/A break;
0N/A default:
0N/A if (nChars < maxchars && ch >= '0') {
0N/A buffer[nChars++] = ch;
0N/A sval = new String(buffer, 0, nChars);
0N/A }
0N/A }
0N/A app.repaint();
0N/A }
0N/A
0N/A public void keyReleased(KeyEvent e) {
0N/A }
0N/A
0N/A public void selected() {
0N/A }
0N/A}
0N/A
3852N/A
0N/Aclass SpreadSheetInput
3852N/A extends InputField {
0N/A
3852N/A public SpreadSheetInput(String initValue,
3852N/A SpreadSheet app,
3852N/A int width,
3852N/A int height,
3852N/A Color bgColor,
3852N/A Color fgColor) {
3852N/A super(initValue, app, width, height, bgColor, fgColor);
3852N/A }
0N/A
3852N/A @Override
0N/A public void selected() {
0N/A float f;
3852N/A sval = ("".equals(sval)) ? "v" : sval;
0N/A switch (sval.charAt(0)) {
3852N/A case 'v':
3852N/A String s = sval.substring(1);
3852N/A try {
3852N/A int i;
3852N/A for (i = 0; i < s.length(); i++) {
3852N/A char c = s.charAt(i);
3852N/A if (c < '0' || c > '9') {
3852N/A break;
3852N/A }
3852N/A }
3852N/A s = s.substring(0, i);
3852N/A f = Float.valueOf(s).floatValue();
3852N/A ((SpreadSheet) app).setCurrentValue(f);
3852N/A } catch (NumberFormatException e) {
3852N/A System.out.println("Not a float: '" + s + "'");
0N/A }
3852N/A break;
3852N/A case 'l':
3852N/A ((SpreadSheet) app).setCurrentValue(Cell.LABEL,
3852N/A sval.substring(1));
3852N/A break;
3852N/A case 'u':
3852N/A ((SpreadSheet) app).setCurrentValue(Cell.URL, sval.substring(1));
3852N/A break;
3852N/A case 'f':
3852N/A ((SpreadSheet) app).setCurrentValue(Cell.FORMULA,
3852N/A sval.substring(1));
3852N/A break;
0N/A }
0N/A }
0N/A}