942 lines
24 KiB
Java
942 lines
24 KiB
Java
/*
|
|
* Adapted 10/98 by Sean Kessler
|
|
* Added arrow key navigation
|
|
* Added cell scrolling
|
|
* Class no longer extends of applet
|
|
*
|
|
* @(#)SpreadSheet.java 1.17 95/03/09 Sami Shaio
|
|
*
|
|
* Copyright (c) 1994-1995 Sun Microsystems, Inc. All Rights Reserved.
|
|
*
|
|
* Permission to use, copy, modify, and distribute this software
|
|
* and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and
|
|
* without fee is hereby granted.
|
|
* Please refer to the file http://java.sun.com/copy_trademarks.html
|
|
* for further important copyright and trademark information and to
|
|
* http://java.sun.com/licensing.html for further important licensing
|
|
* information for the Java (tm) Technology.
|
|
*
|
|
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
|
|
* THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
|
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
* PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
|
|
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
|
|
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
|
|
*
|
|
* THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
|
|
* CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
|
|
* PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
|
|
* NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
|
|
* SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
|
|
* SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
|
|
* PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). SUN
|
|
* SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
|
|
* HIGH RISK ACTIVITIES.
|
|
*/
|
|
import java.applet.Applet;
|
|
import java.awt.*;
|
|
import java.io.*;
|
|
import java.net.*;
|
|
|
|
//******************************************************************************************************
|
|
// ***************************************** SPREADSHEET ***********************************************
|
|
//******************************************************************************************************
|
|
|
|
public class SpreadSheetInterface
|
|
{
|
|
SpreadSheet mSpreadSheet;
|
|
|
|
public SpreadSheetInterface(Applet applet)
|
|
{
|
|
mSpreadSheet=new SpreadSheet(applet,applet.size());
|
|
}
|
|
public SpreadSheetInterface(Applet applet,Dimension controlDimension)
|
|
{
|
|
mSpreadSheet=new SpreadSheet(applet,controlDimension);
|
|
}
|
|
public void update(Graphics graphics)
|
|
{
|
|
mSpreadSheet.update(graphics);
|
|
}
|
|
public void paint(Graphics graphics)
|
|
{
|
|
mSpreadSheet.paint(graphics);
|
|
}
|
|
public boolean mouseDown(Event event,int x,int y)
|
|
{
|
|
return mSpreadSheet.mouseDown(event,x,y);
|
|
}
|
|
public boolean keyDown(Event event,int key)
|
|
{
|
|
return mSpreadSheet.keyDown(event,key);
|
|
}
|
|
public boolean setCellData(int row,int col,String strData)
|
|
{
|
|
return mSpreadSheet.setCellData(row,col,strData);
|
|
}
|
|
public void setDocumentTitle(String strDocumentTitle)
|
|
{
|
|
mSpreadSheet.setDocumentTitle(strDocumentTitle);
|
|
}
|
|
}
|
|
class SpreadSheet
|
|
{
|
|
private final Dimension mCellDimension=new Dimension(100,15);
|
|
private Dimension mControlDimension;
|
|
private String mStrTitle;
|
|
private Font mTitleFont;
|
|
private Color mCellColor;
|
|
private Color mInputColor;
|
|
private int mTitleHeight=15;
|
|
private int mRowLabelWidth=15;
|
|
private boolean mIsStopped=false;
|
|
private boolean mFullUpdate=true;
|
|
private int mRows;
|
|
private int mColumns;
|
|
private int mSelectedRow = -1;
|
|
private int mSelectedColumn = -1;
|
|
private SpreadSheetInput mInputArea;
|
|
private Cell mCells[][];
|
|
private Cell mCurrent=null;
|
|
private int mStartDisplayRow;
|
|
private int mStartDisplayColumn;
|
|
private Applet mApplet;
|
|
|
|
public SpreadSheet(Applet applet,Dimension controlDimension)
|
|
{
|
|
String strParam;
|
|
|
|
mApplet=applet;
|
|
mControlDimension=controlDimension;
|
|
mStartDisplayRow=0;
|
|
mStartDisplayColumn=0;
|
|
mCellColor=Color.white;
|
|
mInputColor=new Color(100, 100, 225);
|
|
mTitleFont=new Font("Courier", Font.BOLD, 12);
|
|
mStrTitle=mApplet.getParameter("title");
|
|
if(null==mStrTitle)mStrTitle="SpreadSheet";
|
|
strParam=mApplet.getParameter("rows");
|
|
if(null==strParam)mRows=9;
|
|
else mRows=Integer.parseInt(strParam);
|
|
strParam=mApplet.getParameter("columns");
|
|
if(null==strParam)mColumns=5;
|
|
else mColumns=Integer.parseInt(strParam);
|
|
mCells=new Cell[mRows][mColumns];
|
|
char strLabel[]=new char[1];
|
|
for(int row=0;row<mRows;row++)
|
|
{
|
|
for(int col=0;col<mColumns;col++)
|
|
{
|
|
mCells[row][col]=new Cell(this,Color.lightGray,Color.black,mCellColor,mCellDimension.width-2,mCellDimension.height-2);
|
|
strLabel[0]=(char)((int)'a'+col);
|
|
strParam=mApplet.getParameter(""+new String(strLabel)+(row+1));
|
|
if(null!=strParam)mCells[row][col].setUnparsedValue(strParam);
|
|
}
|
|
}
|
|
mInputArea=new SpreadSheetInput(null,mApplet,this,mControlDimension.width-2,mCellDimension.height-1,mInputColor,Color.white);
|
|
mApplet.resize(mColumns*mCellDimension.width+mRowLabelWidth,((mRows+1)*mCellDimension.height)+mCellDimension.height+mTitleHeight);
|
|
}
|
|
public void setCurrentValue(float val)
|
|
{
|
|
if(-1==mSelectedRow||-1==mSelectedColumn)return;
|
|
mCells[mSelectedRow][mSelectedColumn].setValue(val);
|
|
mApplet.repaint();
|
|
}
|
|
public void stop()
|
|
{
|
|
stopped(true);
|
|
}
|
|
public void start()
|
|
{
|
|
stopped(false);
|
|
}
|
|
public void stopped(boolean stopped)
|
|
{
|
|
mIsStopped=stopped;
|
|
}
|
|
public boolean stopped()
|
|
{
|
|
return mIsStopped;
|
|
}
|
|
public void destroy()
|
|
{
|
|
}
|
|
public void setCurrentValue(int type,String val)
|
|
{
|
|
if(-1==mSelectedRow||-1==mSelectedColumn)return;
|
|
mCells[mSelectedRow][mSelectedColumn].setValue(type,val);
|
|
mApplet.repaint();
|
|
}
|
|
public void update(Graphics graphics)
|
|
{
|
|
int cx;
|
|
int cy;
|
|
|
|
if(mFullUpdate)
|
|
{
|
|
paint(graphics);
|
|
mFullUpdate=false;
|
|
return;
|
|
}
|
|
graphics.setFont(mTitleFont);
|
|
for(int row=mStartDisplayRow;row<mRows;row++)
|
|
{
|
|
for(int col=mStartDisplayColumn;col<mColumns;col++)
|
|
{
|
|
if(mCells[row][col].needRedisplay())
|
|
{
|
|
cx=(col*mCellDimension.width)+2+mRowLabelWidth;
|
|
cy=((row+1)*mCellDimension.height)+2+mTitleHeight;
|
|
mCells[row][col].paint(graphics,cx,cy);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
public synchronized void paint(Graphics graphics)
|
|
{
|
|
char strLabel[]=new char[1];
|
|
int i;
|
|
int j;
|
|
int cx;
|
|
int cy;
|
|
|
|
graphics.setFont(mTitleFont);
|
|
graphics.drawString(mStrTitle,(mControlDimension.width-graphics.getFontMetrics().stringWidth(mStrTitle))/2,12);
|
|
graphics.setColor(mInputColor);
|
|
graphics.fillRect(0,mCellDimension.height,mControlDimension.width,mCellDimension.height);
|
|
graphics.setFont(mTitleFont);
|
|
for(i=0;i<mRows+1;i++)
|
|
{
|
|
cy=(i+2)*mCellDimension.height;
|
|
graphics.setColor(mApplet.getBackground());
|
|
graphics.draw3DRect(0,cy,mControlDimension.width,2,true);
|
|
if(i<mRows)
|
|
{
|
|
graphics.setColor(mApplet.getBackground());
|
|
graphics.fillRect(1,cy+1,mRowLabelWidth-1,(2*mCellDimension.height)-2);
|
|
graphics.setColor(Color.red);
|
|
graphics.drawString(""+(i+1+mStartDisplayRow),2,cy+12);
|
|
}
|
|
}
|
|
graphics.setColor(Color.red);
|
|
for(i=0;i<mColumns;i++)
|
|
{
|
|
cx=i*mCellDimension.width;
|
|
graphics.setColor(mApplet.getBackground());
|
|
graphics.draw3DRect(cx+mRowLabelWidth,2*mCellDimension.height,1,mControlDimension.height,true);
|
|
}
|
|
for(i=mStartDisplayRow;i<mRows;i++)
|
|
{
|
|
for(j=mStartDisplayColumn;j<mColumns;j++)
|
|
{
|
|
cx=((j-mStartDisplayColumn)*mCellDimension.width)+2+mRowLabelWidth;
|
|
cy=((i+1-mStartDisplayRow)*mCellDimension.height)+2+mTitleHeight;
|
|
if(mCells[i][j]!=null)mCells[i][j].paint(graphics,cx,cy);
|
|
}
|
|
}
|
|
graphics.setColor(mApplet.getBackground());
|
|
graphics.draw3DRect(0,mTitleHeight,mControlDimension.width,mControlDimension.height-mTitleHeight,false);
|
|
mInputArea.paint(graphics,1,mTitleHeight+1);
|
|
}
|
|
public void recalculate()
|
|
{
|
|
for(int row=0;row<mRows;row++)
|
|
{
|
|
for(int col=0;col<mColumns;col++)
|
|
{
|
|
if(mCells[row+mStartDisplayRow][col+mStartDisplayColumn]!=null&&mCells[row+mStartDisplayRow][col+mStartDisplayColumn].type()==Cell.FORMULA)
|
|
{
|
|
mCells[row+mStartDisplayRow][col+mStartDisplayColumn].setRawValue(evaluateFormula(mCells[row+mStartDisplayRow][col+mStartDisplayColumn].parseRoot()));
|
|
mCells[row+mStartDisplayRow][col+mStartDisplayColumn].needRedisplay(true);
|
|
}
|
|
}
|
|
}
|
|
mApplet.repaint();
|
|
}
|
|
private float evaluateFormula(Node node)
|
|
{
|
|
float val=0.0f;
|
|
|
|
if(null==node)return val;
|
|
switch(node.type())
|
|
{
|
|
case Node.OP:
|
|
val=evaluateFormula(node.left());
|
|
switch(node.op())
|
|
{
|
|
case '+':
|
|
val += evaluateFormula(node.right());
|
|
break;
|
|
case '*':
|
|
val *= evaluateFormula(node.right());
|
|
break;
|
|
case '-':
|
|
val -= evaluateFormula(node.right());
|
|
break;
|
|
case '/':
|
|
val /= evaluateFormula(node.right());
|
|
break;
|
|
}
|
|
break;
|
|
case Node.VALUE:
|
|
val=node.value();
|
|
break;
|
|
case Node.CELL:
|
|
if(null==node)break;
|
|
if(null==mCells[node.row()][node.column()])break;
|
|
val=mCells[node.row()][node.column()].value();
|
|
break;
|
|
}
|
|
return val;
|
|
}
|
|
public boolean mouseDown(Event evt,int x,int y)
|
|
{
|
|
if(y<(mTitleHeight+mCellDimension.height))
|
|
{
|
|
mSelectedRow=-1;
|
|
if(y<=mTitleHeight)deselect(true);
|
|
return true;
|
|
}
|
|
if(x<mRowLabelWidth)
|
|
{
|
|
mSelectedRow=-1;
|
|
deselect(true);
|
|
return true;
|
|
}
|
|
mSelectedRow=((y-mCellDimension.height-mTitleHeight)/mCellDimension.height)+mStartDisplayRow;
|
|
mSelectedColumn=(x-mRowLabelWidth)/mCellDimension.width;
|
|
if(mSelectedRow>=mRows||mSelectedColumn>=mColumns)
|
|
{
|
|
mSelectedRow = -1;
|
|
deselect(true);
|
|
return true;
|
|
}
|
|
select();
|
|
return true;
|
|
}
|
|
public boolean keyDown(Event evt, int key)
|
|
{
|
|
mFullUpdate=true;
|
|
if(Key.LeftArrow==key||Key.RightArrow==key||Key.UpArrow==key||Key.DownArrow==key)
|
|
{
|
|
mInputArea.keyDown(Key.Return);
|
|
navigate(key);
|
|
}
|
|
else mInputArea.keyDown(key);
|
|
return true;
|
|
}
|
|
private void navigate(int key)
|
|
{
|
|
switch(key)
|
|
{
|
|
case Key.LeftArrow :
|
|
if(mSelectedColumn<=0)break;
|
|
mSelectedColumn--;
|
|
ensureVisible();
|
|
select();
|
|
break;
|
|
case Key.RightArrow :
|
|
if(mSelectedColumn+1>=mColumns)break;
|
|
mSelectedColumn++;
|
|
ensureVisible();
|
|
select();
|
|
break;
|
|
case Key.UpArrow :
|
|
if(mSelectedRow<=0)break;
|
|
mSelectedRow--;
|
|
ensureVisible();
|
|
select();
|
|
break;
|
|
case Key.DownArrow :
|
|
if(mSelectedRow+1>=mRows)break;
|
|
mSelectedRow++;
|
|
ensureVisible();
|
|
select();
|
|
break;
|
|
}
|
|
}
|
|
private void select()
|
|
{
|
|
Cell cell=mCells[mSelectedRow][mSelectedColumn];
|
|
|
|
if(null!=cell.getPrintString())mInputArea.setText(new String(cell.getPrintString()));
|
|
else mInputArea.setText(new String(""));
|
|
if(mCurrent!=null)mCurrent.deselect();
|
|
mCurrent=cell;
|
|
mCurrent.select();
|
|
mApplet.requestFocus();
|
|
mFullUpdate=true;
|
|
mApplet.repaint();
|
|
}
|
|
private void deselect(boolean destroy)
|
|
{
|
|
if(null==mCurrent)return;
|
|
mCurrent.deselect();
|
|
if(destroy)mCurrent=null;
|
|
}
|
|
private void ensureVisible()
|
|
{
|
|
int yMin=(2*mCellDimension.height)+2+mTitleHeight;
|
|
int xMin=2+mRowLabelWidth+mCellDimension.width;
|
|
Point currPoint=new Point(0,0);
|
|
|
|
currPoint.y=((mSelectedRow-mStartDisplayRow+2)*mCellDimension.height)+2+mTitleHeight;
|
|
currPoint.x=((mSelectedColumn-mStartDisplayColumn)*mCellDimension.width)+2+mRowLabelWidth+mCellDimension.width;
|
|
if(currPoint.y>mControlDimension.height)mStartDisplayRow++;
|
|
else if(currPoint.y<yMin)mStartDisplayRow--;
|
|
if(currPoint.x>mControlDimension.width)mStartDisplayColumn++;
|
|
else if(currPoint.x<xMin)mStartDisplayColumn--;
|
|
}
|
|
public Applet applet()
|
|
{
|
|
return mApplet;
|
|
}
|
|
public int rows()
|
|
{
|
|
return mRows;
|
|
}
|
|
public int columns()
|
|
{
|
|
return mColumns;
|
|
}
|
|
public boolean setCellData(int row,int col,String strData)
|
|
{
|
|
String strCellData;
|
|
if(row>=mRows||col>=mColumns)return false;
|
|
strCellData="l";
|
|
strCellData+=strData;
|
|
mCells[row][col].setUnparsedValue(strCellData);
|
|
mApplet.repaint();
|
|
return true;
|
|
}
|
|
public void setDocumentTitle(String strDocumentTitle)
|
|
{
|
|
mStrTitle=strDocumentTitle;
|
|
}
|
|
}
|
|
|
|
//******************************************************************************************************
|
|
// ******************************************** CELL ***************************************************
|
|
//******************************************************************************************************
|
|
class Cell
|
|
{
|
|
public static final int VALUE = 0;
|
|
public static final int LABEL = 1;
|
|
public static final int URL = 2;
|
|
public static final int FORMULA = 3;
|
|
|
|
private Node mParseRoot;
|
|
private boolean mNeedRedisplay;
|
|
private boolean mSelected = false;
|
|
private boolean mTransientValue = false;
|
|
private int mType=Cell.VALUE;
|
|
private String mValueString = "";
|
|
private String mPrintString = "v";
|
|
private float mValue;
|
|
private Color mBgColor;
|
|
private Color mFgColor;
|
|
private Color mHighlightColor;
|
|
private int mWidth;
|
|
private int mHeight;
|
|
private SpreadSheet mSpreadSheet;
|
|
private boolean mPaused=false;
|
|
|
|
public Cell(SpreadSheet spreadSheet,Color bgColor,Color fgColor,Color highlightColor,int width,int height)
|
|
{
|
|
mSpreadSheet=spreadSheet;
|
|
mBgColor=bgColor;
|
|
mFgColor=fgColor;
|
|
mHighlightColor=highlightColor;
|
|
mWidth=width;
|
|
mHeight=height;
|
|
mNeedRedisplay=true;
|
|
}
|
|
public void setRawValue(float value)
|
|
{
|
|
mValueString=Float.toString(value);
|
|
mValue=value;
|
|
}
|
|
public void setValue(float value)
|
|
{
|
|
setRawValue(value);
|
|
mPrintString="v"+mValueString;
|
|
mType=Cell.VALUE;
|
|
mPaused=false;
|
|
mSpreadSheet.recalculate();
|
|
mNeedRedisplay=true;
|
|
}
|
|
public void setTransientValue(float value)
|
|
{
|
|
mTransientValue=true;
|
|
mValue=value;
|
|
mNeedRedisplay=true;
|
|
mSpreadSheet.recalculate();
|
|
}
|
|
public void setUnparsedValue(String s)
|
|
{
|
|
switch (s.charAt(0))
|
|
{
|
|
case 'v':
|
|
setValue(Cell.VALUE, s.substring(1));
|
|
break;
|
|
case 'f':
|
|
setValue(Cell.FORMULA, s.substring(1));
|
|
break;
|
|
case 'l':
|
|
setValue(Cell.LABEL, s.substring(1));
|
|
break;
|
|
case 'u':
|
|
setValue(Cell.URL, s.substring(1));
|
|
break;
|
|
}
|
|
}
|
|
public String parseFormula(String formula, Node node)
|
|
{
|
|
String subformula;
|
|
String restFormula;
|
|
float value;
|
|
int length = formula.length();
|
|
Node left;
|
|
Node right;
|
|
char op;
|
|
|
|
if(null==formula)return null;
|
|
subformula=parseValue(formula, node);
|
|
if(null==subformula||0==subformula.length())return null;
|
|
if(subformula==formula)return formula;
|
|
switch(op=subformula.charAt(0))
|
|
{
|
|
case 0:
|
|
return null;
|
|
case ')':
|
|
return subformula;
|
|
case '+':
|
|
case '*':
|
|
case '-':
|
|
case '/':
|
|
restFormula = subformula.substring(1);
|
|
subformula = parseValue(restFormula, right=new Node());
|
|
if(subformula != restFormula)
|
|
{
|
|
left = new Node(node);
|
|
node.left(left);
|
|
node.right(right);
|
|
node.op(op);
|
|
node.type(Node.OP);
|
|
return subformula;
|
|
}
|
|
else return formula;
|
|
default:
|
|
return formula;
|
|
}
|
|
}
|
|
public String parseValue(String formula, Node node)
|
|
{
|
|
char c=formula.charAt(0);
|
|
String subformula;
|
|
String restFormula;
|
|
float value;
|
|
int row;
|
|
int column;
|
|
|
|
restFormula = formula;
|
|
if (c == '(')
|
|
{
|
|
restFormula = formula.substring(1);
|
|
subformula = parseFormula(restFormula, node);
|
|
if(subformula == null || subformula.length() == restFormula.length())return formula;
|
|
else if (! (subformula.charAt(0) == ')'))return formula;
|
|
restFormula = subformula;
|
|
}
|
|
else if (c >= '0' && c <= '9')
|
|
{
|
|
int i;
|
|
|
|
try{value = Float.valueOf(formula).floatValue();}
|
|
catch (NumberFormatException exception){return formula;}
|
|
for (i=0; i < formula.length(); i++)
|
|
{
|
|
c = formula.charAt(i);
|
|
if ((c < '0' || c > '9') && c != '.')break;
|
|
}
|
|
node.type(Node.VALUE);
|
|
node.value(value);
|
|
restFormula = formula.substring(i);
|
|
return restFormula;
|
|
}
|
|
else if (c >= 'A' && c <= 'Z')
|
|
{
|
|
int i;
|
|
|
|
column = c - 'A';
|
|
restFormula = formula.substring(1);
|
|
row = Float.valueOf(restFormula).intValue();
|
|
for(i=0; i < restFormula.length(); i++)
|
|
{
|
|
c = restFormula.charAt(i);
|
|
if (c < '0' || c > '9')break;
|
|
}
|
|
node.row(row-1);
|
|
node.column(column);
|
|
node.type(Node.CELL);
|
|
if (i == restFormula.length())restFormula=null;
|
|
else
|
|
{
|
|
restFormula = restFormula.substring(i);
|
|
if (restFormula.charAt(0) == 0)return null;
|
|
}
|
|
}
|
|
return restFormula;
|
|
}
|
|
public void setValue(int type, String s)
|
|
{
|
|
mPaused=false;
|
|
mValueString=new String(s);
|
|
mType=type;
|
|
mNeedRedisplay=true;
|
|
switch(mType)
|
|
{
|
|
case Cell.VALUE:
|
|
setValue(Float.valueOf(s).floatValue());
|
|
break;
|
|
case Cell.LABEL:
|
|
mPrintString = "l" + mValueString;
|
|
break;
|
|
case Cell.URL:
|
|
mPrintString = "u" + mValueString;
|
|
break;
|
|
case Cell.FORMULA:
|
|
parseFormula(mValueString,mParseRoot=new Node());
|
|
mPrintString = "f" + mValueString;
|
|
break;
|
|
}
|
|
mSpreadSheet.recalculate();
|
|
}
|
|
public String getValueString()
|
|
{
|
|
return mValueString;
|
|
}
|
|
public String getPrintString()
|
|
{
|
|
return mPrintString;
|
|
}
|
|
public void select()
|
|
{
|
|
mSelected=true;
|
|
mPaused=true;
|
|
}
|
|
public void deselect()
|
|
{
|
|
mSelected=false;
|
|
mPaused=false;
|
|
mNeedRedisplay=true;
|
|
mSpreadSheet.applet().repaint();
|
|
}
|
|
public void paint(Graphics graphics,int x,int y)
|
|
{
|
|
if(mSelected)graphics.setColor(mHighlightColor);
|
|
else graphics.setColor(mBgColor);
|
|
graphics.fillRect(x+1,y+1,mWidth-1,mHeight-1);
|
|
if(null!=mValueString)
|
|
{
|
|
switch(mType)
|
|
{
|
|
case Cell.VALUE:
|
|
case Cell.LABEL:
|
|
graphics.setColor(mFgColor);
|
|
break;
|
|
case Cell.FORMULA:
|
|
graphics.setColor(Color.red);
|
|
break;
|
|
case Cell.URL:
|
|
graphics.setColor(Color.blue);
|
|
break;
|
|
}
|
|
if(!mTransientValue)
|
|
{
|
|
if(mValueString.length()>14)graphics.drawString(mValueString.substring(0,14),x,y+(mHeight/2)+5);
|
|
else graphics.drawString(mValueString,x,y+(mHeight/2)+5);
|
|
}
|
|
else graphics.drawString(""+mValue,x,y+(mHeight/2)+5);
|
|
mNeedRedisplay=false;
|
|
}
|
|
}
|
|
public int type()
|
|
{
|
|
return mType;
|
|
}
|
|
public Node parseRoot()
|
|
{
|
|
return mParseRoot;
|
|
}
|
|
public void needRedisplay(boolean needRedisplay)
|
|
{
|
|
mNeedRedisplay=needRedisplay;
|
|
}
|
|
public boolean needRedisplay()
|
|
{
|
|
return mNeedRedisplay;
|
|
}
|
|
public float value()
|
|
{
|
|
return mValue;
|
|
}
|
|
public SpreadSheet spreadSheet()
|
|
{
|
|
return mSpreadSheet;
|
|
}
|
|
public boolean paused()
|
|
{
|
|
return mPaused;
|
|
}
|
|
}
|
|
//******************************************************************************************************
|
|
// *************************************** NODE *******************************************************
|
|
//******************************************************************************************************
|
|
class Node
|
|
{
|
|
public static final int OP = 0;
|
|
public static final int VALUE = 1;
|
|
public static final int CELL = 2;
|
|
private int mType;
|
|
private Node mLeft;
|
|
private Node mRight;
|
|
private int mRow;
|
|
private int mColumn;
|
|
private float mValue;
|
|
private char mOp;
|
|
|
|
public Node()
|
|
{
|
|
mLeft=null;
|
|
mRight=null;
|
|
mValue=0;
|
|
mRow=-1;
|
|
mColumn=-1;
|
|
mOp=0;
|
|
mType=Node.VALUE;
|
|
}
|
|
public Node(Node node)
|
|
{
|
|
mLeft=node.mLeft;
|
|
mRight=node.mRight;
|
|
mValue=node.mValue;
|
|
mRow=node.mRow;
|
|
mColumn=node.mColumn;
|
|
mOp=node.mOp;
|
|
mType=node.mType;
|
|
}
|
|
public void print(int indentLevel)
|
|
{
|
|
char l[] = new char[1];
|
|
switch(mType)
|
|
{
|
|
case Node.VALUE:
|
|
break;
|
|
case Node.CELL:
|
|
l[0] = (char)((int)'A' + column());
|
|
break;
|
|
case Node.OP:
|
|
mLeft.print(indentLevel + 3);
|
|
mRight.print(indentLevel + 3);
|
|
break;
|
|
}
|
|
}
|
|
public int type()
|
|
{
|
|
return mType;
|
|
}
|
|
public void type(int type)
|
|
{
|
|
mType=type;
|
|
}
|
|
public float value()
|
|
{
|
|
return mValue;
|
|
}
|
|
public void value(float value)
|
|
{
|
|
mValue=value;
|
|
}
|
|
public Node left()
|
|
{
|
|
return mLeft;
|
|
}
|
|
public void left(Node left)
|
|
{
|
|
mLeft=left;
|
|
}
|
|
public Node right()
|
|
{
|
|
return mRight;
|
|
}
|
|
public void right(Node right)
|
|
{
|
|
mRight=right;
|
|
}
|
|
public char op()
|
|
{
|
|
return mOp;
|
|
}
|
|
public void op(char op)
|
|
{
|
|
mOp=op;
|
|
}
|
|
public int row()
|
|
{
|
|
return mRow;
|
|
}
|
|
public void row(int row)
|
|
{
|
|
mRow=row;
|
|
}
|
|
public int column()
|
|
{
|
|
return mColumn;
|
|
}
|
|
public void column(int column)
|
|
{
|
|
mColumn=column;
|
|
}
|
|
}
|
|
|
|
class InputField
|
|
{
|
|
private int mMaxchars = 50;
|
|
private Applet mApplet;
|
|
private String mStringValue;
|
|
private char mBuffer[];
|
|
private int mChars;
|
|
private int mWidth;
|
|
private int mHeight;
|
|
private Color mBgColor;
|
|
private Color mFgColor;
|
|
|
|
public InputField(String initValue,Applet applet,int width,int height,Color bgColor, Color fgColor)
|
|
{
|
|
mWidth=width;
|
|
mHeight=height;
|
|
mBgColor=bgColor;
|
|
mFgColor=fgColor;
|
|
mApplet=applet;
|
|
mBuffer = new char[mMaxchars];
|
|
mChars = 0;
|
|
if(initValue != null)
|
|
{
|
|
initValue.getChars(0, initValue.length(),mBuffer, 0);
|
|
mChars = initValue.length();
|
|
}
|
|
mStringValue=initValue;
|
|
}
|
|
public void setText(String val)
|
|
{
|
|
int i;
|
|
for(i=0; i < mMaxchars; i++)mBuffer[i] = 0;
|
|
mStringValue=new String(val);
|
|
if (val == null)
|
|
{
|
|
mStringValue= "";
|
|
mChars = 0;
|
|
mBuffer[0] = 0;
|
|
}
|
|
else
|
|
{
|
|
mStringValue.getChars(0,mStringValue.length(), mBuffer, 0);
|
|
mChars = val.length();
|
|
mStringValue = new String(mBuffer);
|
|
}
|
|
}
|
|
public String getValue()
|
|
{
|
|
return mStringValue;
|
|
}
|
|
public void paint(Graphics g, int x, int y)
|
|
{
|
|
g.setColor(mBgColor);
|
|
g.fillRect(x, y,mWidth,mHeight);
|
|
if(mStringValue!= null)
|
|
{
|
|
g.setColor(mFgColor);
|
|
g.drawString(mStringValue, x, y + (mHeight / 2) + 3);
|
|
}
|
|
}
|
|
public void mouseUp(int x, int y)
|
|
{
|
|
}
|
|
public void keyDown(int key)
|
|
{
|
|
if(mChars<mMaxchars)
|
|
{
|
|
switch(key)
|
|
{
|
|
case Key.BackSpace :
|
|
--mChars;
|
|
if(mChars<0)mChars=0;
|
|
mBuffer[mChars] = 0;
|
|
mStringValue = new String(new String(mBuffer));
|
|
break;
|
|
case Key.Return :
|
|
selected();
|
|
break;
|
|
default:
|
|
mBuffer[mChars++] = (char)key;
|
|
mStringValue = new String(new String(mBuffer));
|
|
break;
|
|
}
|
|
}
|
|
mApplet.repaint();
|
|
}
|
|
public void selected()
|
|
{
|
|
}
|
|
public Applet applet()
|
|
{
|
|
return mApplet;
|
|
}
|
|
}
|
|
|
|
class SpreadSheetInput extends InputField
|
|
{
|
|
SpreadSheet mSpreadSheet;
|
|
|
|
public SpreadSheetInput(String initValue,Applet app,SpreadSheet spreadSheet,int width,int height,Color bgColor,Color fgColor)
|
|
{
|
|
super(initValue,app,width,height,bgColor,fgColor);
|
|
mSpreadSheet=spreadSheet;
|
|
}
|
|
public void selected()
|
|
{
|
|
float f;
|
|
|
|
switch(getValue().charAt(0))
|
|
{
|
|
case 'v':
|
|
try{f=Float.valueOf(getValue().substring(1)).floatValue();mSpreadSheet.setCurrentValue(f);}
|
|
catch(Exception exception){;}
|
|
break;
|
|
case 'l':
|
|
mSpreadSheet.setCurrentValue(Cell.LABEL,getValue().substring(1));
|
|
break;
|
|
case 'u':
|
|
mSpreadSheet.setCurrentValue(Cell.URL,getValue().substring(1));
|
|
break;
|
|
case 'f':
|
|
mSpreadSheet.setCurrentValue(Cell.FORMULA,getValue().substring(1));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
class Key
|
|
{
|
|
public static final int LeftArrow=1006;
|
|
public static final int RightArrow=1007;
|
|
public static final int UpArrow=1004;
|
|
public static final int DownArrow=1005;
|
|
public static final int BackSpace=8;
|
|
public static final int Return=10;
|
|
public Key()
|
|
{
|
|
}
|
|
};
|