/* * 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; SpreadSheetInteraface(Applet applet) { mSpreadSheet=new SpreadSheet(applet,applet.size()); } SpreadSheetInterface(Applet applet,Dimension controlDimension) { mSpreadSheet=new SpreadSheet(applet,controlDimension); } } //public class SpreadSheet 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||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; } public Applet applet() { return mApplet; } 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.ymControlDimension.width)mStartDisplayColumn++; else if(currPoint.x= '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