Initial
This commit is contained in:
BIN
java/SPREAD/CASHFL~1.CLA
Normal file
BIN
java/SPREAD/CASHFL~1.CLA
Normal file
Binary file not shown.
312
java/SPREAD/CASHFL~1.JAV
Normal file
312
java/SPREAD/CASHFL~1.JAV
Normal file
@@ -0,0 +1,312 @@
|
||||
import java.awt.*;
|
||||
|
||||
public class Cashflow extends java.applet.Applet
|
||||
{
|
||||
SpreadSheetInterface mSpreadSheet;
|
||||
PurePassThru mPurePassThru=new PurePassThru();
|
||||
PureCashflow mPureCashflows[];
|
||||
TextField mCtlPrincipal;
|
||||
TextField mCtlInterest;
|
||||
TextField mCtlTerm;
|
||||
TextField mCtlPrepayment;
|
||||
TextField mCtlIncrement;
|
||||
TextField mCtlFrequency;
|
||||
Label mCtlCost;
|
||||
Label mCtlMsg;
|
||||
Button mCtlButton;
|
||||
|
||||
public void init()
|
||||
{
|
||||
performLayout();
|
||||
mSpreadSheet=new SpreadSheetInterface(this,361,10,new Dimension(630,200));
|
||||
mSpreadSheet.setDocumentTitle("Paydown Calculator v1.00");
|
||||
mSpreadSheet.gridLock(true);
|
||||
repaint();
|
||||
}
|
||||
public void update(Graphics graphics)
|
||||
{
|
||||
if(null!=mSpreadSheet)mSpreadSheet.update(graphics);
|
||||
}
|
||||
public void paint(Graphics graphics)
|
||||
{
|
||||
if(null!=mSpreadSheet)mSpreadSheet.paint(graphics);
|
||||
}
|
||||
public boolean mouseDown(Event event,int x,int y)
|
||||
{
|
||||
if(null!=mCtlPrincipal&&mCtlPrincipal==event.target)return false;
|
||||
else if(null!=mCtlInterest&&mCtlInterest==event.target)return false;
|
||||
else if(null!=mCtlTerm&&mCtlTerm==event.target)return false;
|
||||
else if(null!=mCtlButton&&mCtlButton==event.target)return false;
|
||||
else if(null!=mCtlPrepayment&&mCtlPrepayment==event.target)return false;
|
||||
else if(null!=mCtlIncrement&&mCtlIncrement==event.target)return false;
|
||||
else if(null!=mCtlFrequency&&mCtlFrequency==event.target)return false;
|
||||
else if(null!=mSpreadSheet)return mSpreadSheet.mouseDown(event,x,y);
|
||||
return true;
|
||||
}
|
||||
public boolean keyDown(Event event,int key)
|
||||
{
|
||||
if(null!=mCtlPrincipal&&mCtlPrincipal==event.target)return false;
|
||||
else if(null!=mCtlInterest&&mCtlInterest==event.target)return false;
|
||||
else if(null!=mCtlTerm&&mCtlTerm==event.target)return false;
|
||||
else if(null!=mCtlButton&&mCtlButton==event.target)return false;
|
||||
else if(null!=mCtlPrepayment&&mCtlPrepayment==event.target)return false;
|
||||
else if(null!=mCtlIncrement&&mCtlIncrement==event.target)return false;
|
||||
else if(null!=mCtlFrequency&&mCtlFrequency==event.target)return false;
|
||||
else if(null!=mSpreadSheet)return mSpreadSheet.keyDown(event,key);
|
||||
return true;
|
||||
}
|
||||
public void performLayout()
|
||||
{
|
||||
GridBagLayout layout=new GridBagLayout();
|
||||
GridBagConstraints constraints=new GridBagConstraints();
|
||||
setFont(new Font("Fixed",Font.BOLD,12));
|
||||
setLayout(layout);
|
||||
|
||||
constraints.fill=GridBagConstraints.BOTH;
|
||||
constraints.weightx=0.25;
|
||||
Label prnLabel=new Label("Principal",Label.LEFT);
|
||||
layout.setConstraints(prnLabel,constraints);
|
||||
add(prnLabel);
|
||||
mCtlPrincipal=new TextField("$100000.00");
|
||||
layout.setConstraints(mCtlPrincipal,constraints);
|
||||
add(mCtlPrincipal);
|
||||
|
||||
Label intLabel=new Label("Interest",Label.LEFT);
|
||||
layout.setConstraints(intLabel,constraints);
|
||||
add(intLabel);
|
||||
mCtlInterest=new TextField("8.00%");
|
||||
layout.setConstraints(mCtlInterest,constraints);
|
||||
add(mCtlInterest);
|
||||
|
||||
Label trmLabel=new Label("Term",Label.LEFT);
|
||||
layout.setConstraints(trmLabel,constraints);
|
||||
add(trmLabel);
|
||||
mCtlTerm=new TextField("360");
|
||||
layout.setConstraints(mCtlTerm,constraints);
|
||||
add(mCtlTerm);
|
||||
constraints.gridwidth=GridBagConstraints.REMAINDER;
|
||||
mCtlButton=new Button("Calculate");
|
||||
layout.setConstraints(mCtlButton,constraints);
|
||||
add(mCtlButton);
|
||||
|
||||
constraints.fill=GridBagConstraints.BOTH;
|
||||
constraints.gridwidth=1;
|
||||
Label ppyLabel=new Label("Prepayment",Label.LEFT);
|
||||
layout.setConstraints(ppyLabel,constraints);
|
||||
add(ppyLabel);
|
||||
mCtlPrepayment=new TextField("$0.00");
|
||||
layout.setConstraints(mCtlPrepayment,constraints);
|
||||
add(mCtlPrepayment);
|
||||
constraints.gridwidth=GridBagConstraints.REMAINDER;
|
||||
Label ppyHlpLabel=new Label("Enter the amount of your prepayment(s).");
|
||||
layout.setConstraints(ppyHlpLabel,constraints);
|
||||
add(ppyHlpLabel);
|
||||
|
||||
|
||||
|
||||
constraints.fill=GridBagConstraints.BOTH;
|
||||
constraints.gridwidth=1;
|
||||
Label incLabel=new Label("Increment",Label.LEFT);
|
||||
layout.setConstraints(incLabel,constraints);
|
||||
add(incLabel);
|
||||
mCtlIncrement=new TextField("$0.00");
|
||||
layout.setConstraints(mCtlIncrement,constraints);
|
||||
add(mCtlIncrement);
|
||||
constraints.gridwidth=GridBagConstraints.REMAINDER;
|
||||
Label incHlpLabel=new Label("Increment the prepayment(s) by this amount.");
|
||||
layout.setConstraints(incHlpLabel,constraints);
|
||||
add(incHlpLabel);
|
||||
|
||||
|
||||
constraints.fill=GridBagConstraints.BOTH;
|
||||
constraints.gridwidth=1;
|
||||
Label frqLabel=new Label("Frequency",Label.LEFT);
|
||||
layout.setConstraints(frqLabel,constraints);
|
||||
add(frqLabel);
|
||||
mCtlFrequency=new TextField("0.00");
|
||||
layout.setConstraints(mCtlFrequency,constraints);
|
||||
add(mCtlFrequency);
|
||||
constraints.gridwidth=GridBagConstraints.REMAINDER;
|
||||
Label frqHlpLabel=new Label("Frequency at which to increment the prepayments (ie) number of months.");
|
||||
layout.setConstraints(frqHlpLabel,constraints);
|
||||
add(frqHlpLabel);
|
||||
|
||||
constraints.fill=GridBagConstraints.BOTH;
|
||||
constraints.gridwidth=1;
|
||||
Label costLabel=new Label("Cost Of Capital:",Label.LEFT);
|
||||
layout.setConstraints(costLabel,constraints);
|
||||
add(costLabel);
|
||||
mCtlCost=new Label("$0.00",Label.LEFT);
|
||||
// constraints.gridwidth=GridBagConstraints.REMAINDER;
|
||||
layout.setConstraints(mCtlCost,constraints);
|
||||
add(mCtlCost);
|
||||
mCtlMsg=new Label("",Label.LEFT);
|
||||
constraints.gridwidth=GridBagConstraints.REMAINDER;
|
||||
layout.setConstraints(mCtlMsg,constraints);
|
||||
add(mCtlMsg);
|
||||
}
|
||||
public boolean action(Event event,Object object)
|
||||
{
|
||||
if(null!=mCtlButton&&mCtlButton==event.target)performCalc();
|
||||
return true;
|
||||
}
|
||||
public void performCalc()
|
||||
{
|
||||
Prepayment prepayment=new Prepayment();
|
||||
String strPrincipal=mCtlPrincipal.getText();
|
||||
String strInterest=mCtlInterest.getText();
|
||||
String strTerm=mCtlTerm.getText();
|
||||
String strPrepayment=mCtlPrepayment.getText();
|
||||
String strIncrement=mCtlIncrement.getText();
|
||||
String strFrequency=mCtlFrequency.getText();
|
||||
Double workDouble;
|
||||
double principal;
|
||||
double interest;
|
||||
int term;
|
||||
int itemIndex;
|
||||
|
||||
workDouble=new Double(0);
|
||||
strPrincipal=strPrincipal.replace('$',' ');
|
||||
workDouble=workDouble.valueOf(strPrincipal);
|
||||
principal=workDouble.doubleValue();
|
||||
strInterest=strInterest.replace('%',' ');
|
||||
workDouble=workDouble.valueOf(strInterest);
|
||||
interest=workDouble.doubleValue();
|
||||
term=Integer.parseInt(strTerm);
|
||||
strPrepayment=strPrepayment.replace('$',' ');
|
||||
workDouble=workDouble.valueOf(strPrepayment);
|
||||
prepayment.amount(workDouble.doubleValue());
|
||||
strIncrement=strIncrement.replace('$',' ');
|
||||
workDouble=workDouble.valueOf(strIncrement);
|
||||
prepayment.increment(workDouble.doubleValue());
|
||||
workDouble=workDouble.valueOf(strFrequency);
|
||||
prepayment.frequency(workDouble.doubleValue());
|
||||
|
||||
mPurePassThru.issBal(principal);
|
||||
mPurePassThru.wac(interest);
|
||||
mPurePassThru.coupon(interest);
|
||||
mPurePassThru.wam((short)term);
|
||||
mPurePassThru.origTerm((short)term);
|
||||
mPurePassThru.psa(0.00);
|
||||
mCtlMsg.setText("Please wait a few moments...");
|
||||
mCtlMsg.repaint();
|
||||
if(0.00!=prepayment.amount()||0.00!=prepayment.increment())generateFlows(prepayment);
|
||||
else generateFlows();
|
||||
Money money=new Money(0);
|
||||
mSpreadSheet.clear();
|
||||
repaint();
|
||||
mSpreadSheet.setCellData(0,0,"BeginBal");
|
||||
mSpreadSheet.setCellData(0,1,"SMM");
|
||||
mSpreadSheet.setCellData(0,2,"MtgPay");
|
||||
mSpreadSheet.setCellData(0,3,"NetIntPay");
|
||||
mSpreadSheet.setCellData(0,4,"GrossIntPay");
|
||||
mSpreadSheet.setCellData(0,5,"SchedPrinPay");
|
||||
mSpreadSheet.setCellData(0,6,"Prepayment");
|
||||
mSpreadSheet.setCellData(0,7,"TotPrin");
|
||||
mSpreadSheet.setCellData(0,8,"Cashflow");
|
||||
mSpreadSheet.setCellData(0,9,"Factor");
|
||||
|
||||
for(itemIndex=0;itemIndex<mPurePassThru.wam();itemIndex++)
|
||||
{
|
||||
if(mPureCashflows[itemIndex]==null)break;
|
||||
money.setValue(mPureCashflows[itemIndex].beginBal());
|
||||
mSpreadSheet.setCellData(itemIndex+1,0,money.toString());
|
||||
money.setValue(mPureCashflows[itemIndex].smm());
|
||||
mSpreadSheet.setCellData(itemIndex+1,1,money.toString());
|
||||
money.setValue(mPureCashflows[itemIndex].mtgPay());
|
||||
mSpreadSheet.setCellData(itemIndex+1,2,money.toString());
|
||||
money.setValue(mPureCashflows[itemIndex].netIntPay());
|
||||
mSpreadSheet.setCellData(itemIndex+1,3,money.toString());
|
||||
money.setValue(mPureCashflows[itemIndex].grossIntPay());
|
||||
mSpreadSheet.setCellData(itemIndex+1,4,money.toString());
|
||||
money.setValue(mPureCashflows[itemIndex].schedPrinPay());
|
||||
mSpreadSheet.setCellData(itemIndex+1,5,money.toString());
|
||||
money.setValue(mPureCashflows[itemIndex].prepayment());
|
||||
mSpreadSheet.setCellData(itemIndex+1,6,money.toString());
|
||||
money.setValue(mPureCashflows[itemIndex].totPrin());
|
||||
mSpreadSheet.setCellData(itemIndex+1,7,money.toString());
|
||||
money.setValue(mPureCashflows[itemIndex].cashflow());
|
||||
mSpreadSheet.setCellData(itemIndex+1,8,money.toString());
|
||||
mSpreadSheet.setCellData(itemIndex+1,9,String.valueOf(mPureCashflows[itemIndex].factor()));
|
||||
}
|
||||
money.setValue(mPureCashflows[itemIndex-1].grossIntPay());
|
||||
mCtlCost.setText(money.toString());
|
||||
mCtlMsg.setText("Calculations complete.");
|
||||
repaint();
|
||||
}
|
||||
public void generateFlows()
|
||||
{
|
||||
double issBal;
|
||||
double tmpCPR;
|
||||
int actualMonth;
|
||||
int indexFlows;
|
||||
|
||||
indexFlows=0;
|
||||
mPureCashflows=new PureCashflow[mPurePassThru.wam()];
|
||||
issBal=mPurePassThru.issBal();
|
||||
for(int wam=mPurePassThru.wam();wam>0&&issBal>0.00;wam--)
|
||||
{
|
||||
mPureCashflows[indexFlows]=new PureCashflow();
|
||||
actualMonth=(mPurePassThru.origTerm()-wam)+1;
|
||||
if(actualMonth<=30)tmpCPR=.002*(double)actualMonth;
|
||||
else tmpCPR=.06;
|
||||
mPureCashflows[indexFlows].beginBal(issBal);
|
||||
mPureCashflows[indexFlows].smm(1.00-Math.pow(1.00-(tmpCPR*mPurePassThru.psa()/100.00),1.00/12.00));
|
||||
if(0==indexFlows)mPureCashflows[indexFlows].mtgPay((issBal*(mPurePassThru.wac()/1200.00))/
|
||||
(1.00-Math.pow(1.00/(1.00+(mPurePassThru.wac()/1200.00)),(double)wam)));
|
||||
else mPureCashflows[indexFlows].mtgPay(mPureCashflows[indexFlows-1].mtgPay());
|
||||
if(issBal<=mPureCashflows[indexFlows].mtgPay())mPureCashflows[indexFlows].mtgPay(issBal);
|
||||
mPureCashflows[indexFlows].netIntPay(issBal*(mPurePassThru.coupon()/1200.00));
|
||||
if(0==indexFlows)mPureCashflows[indexFlows].grossIntPay(mPureCashflows[indexFlows].netIntPay());
|
||||
else mPureCashflows[indexFlows].grossIntPay(mPureCashflows[indexFlows-1].grossIntPay()+mPureCashflows[indexFlows].netIntPay());
|
||||
mPureCashflows[indexFlows].schedPrinPay(mPureCashflows[indexFlows].mtgPay()-mPureCashflows[indexFlows].netIntPay());
|
||||
mPureCashflows[indexFlows].prepayment(0.00);
|
||||
mPureCashflows[indexFlows].totPrin(mPureCashflows[indexFlows].schedPrinPay()+mPureCashflows[indexFlows].prepayment());
|
||||
mPureCashflows[indexFlows].cashflow(mPureCashflows[indexFlows].netIntPay()+mPureCashflows[indexFlows].totPrin());
|
||||
mPureCashflows[indexFlows].factor(issBal/mPurePassThru.issBal());
|
||||
issBal-=mPureCashflows[indexFlows].totPrin();
|
||||
indexFlows++;
|
||||
}
|
||||
}
|
||||
public void generateFlows(Prepayment prepayment)
|
||||
{
|
||||
double issBal;
|
||||
double tmpCPR;
|
||||
int actualMonth;
|
||||
int indexFlows;
|
||||
|
||||
indexFlows=0;
|
||||
mPureCashflows=new PureCashflow[mPurePassThru.wam()];
|
||||
issBal=mPurePassThru.issBal();
|
||||
for(int wam=mPurePassThru.wam();wam>0&&issBal>0.00;wam--)
|
||||
{
|
||||
mPureCashflows[indexFlows]=new PureCashflow();
|
||||
actualMonth=(mPurePassThru.origTerm()-wam)+1;
|
||||
if(actualMonth<=30)tmpCPR=.002*(double)actualMonth;
|
||||
else tmpCPR=.06;
|
||||
mPureCashflows[indexFlows].beginBal(issBal);
|
||||
mPureCashflows[indexFlows].smm(1.00-Math.pow(1.00-(tmpCPR*mPurePassThru.psa()/100.00),1.00/12.00));
|
||||
if(0==indexFlows)mPureCashflows[indexFlows].mtgPay((issBal*(mPurePassThru.wac()/1200.00))/
|
||||
(1.00-Math.pow(1.00/(1.00+(mPurePassThru.wac()/1200.00)),(double)wam)));
|
||||
else mPureCashflows[indexFlows].mtgPay(mPureCashflows[indexFlows-1].mtgPay());
|
||||
if(issBal<=mPureCashflows[indexFlows].mtgPay())mPureCashflows[indexFlows].mtgPay(issBal);
|
||||
mPureCashflows[indexFlows].netIntPay(issBal*(mPurePassThru.coupon()/1200.00));
|
||||
if(0==indexFlows)mPureCashflows[indexFlows].grossIntPay(mPureCashflows[indexFlows].netIntPay());
|
||||
else mPureCashflows[indexFlows].grossIntPay(mPureCashflows[indexFlows-1].grossIntPay()+mPureCashflows[indexFlows].netIntPay());
|
||||
mPureCashflows[indexFlows].schedPrinPay(mPureCashflows[indexFlows].mtgPay()-mPureCashflows[indexFlows].netIntPay());
|
||||
mPureCashflows[indexFlows].prepayment(prepayment.amount());
|
||||
prepayment.period(prepayment.period()+1);
|
||||
if(prepayment.period()>prepayment.frequency())
|
||||
{
|
||||
prepayment.amount(prepayment.amount()+prepayment.increment());
|
||||
prepayment.period(1);
|
||||
}
|
||||
mPureCashflows[indexFlows].totPrin(mPureCashflows[indexFlows].schedPrinPay()+mPureCashflows[indexFlows].prepayment());
|
||||
mPureCashflows[indexFlows].cashflow(mPureCashflows[indexFlows].netIntPay()+mPureCashflows[indexFlows].totPrin());
|
||||
mPureCashflows[indexFlows].factor(issBal/mPurePassThru.issBal());
|
||||
issBal-=mPureCashflows[indexFlows].totPrin();
|
||||
indexFlows++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIN
java/SPREAD/CELL~1.CLA
Normal file
BIN
java/SPREAD/CELL~1.CLA
Normal file
Binary file not shown.
897
java/SPREAD/HOLD/SPREAD~1.JAV
Normal file
897
java/SPREAD/HOLD/SPREAD~1.JAV
Normal file
@@ -0,0 +1,897 @@
|
||||
/*
|
||||
* 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;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);
|
||||
graphics.clipRect(0,0,mControlDimension.width,mControlDimension.height);
|
||||
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.clipRect(0,0,mControlDimension.width,mControlDimension.height);
|
||||
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;
|
||||
}
|
||||
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.y<yMin)mStartDisplayRow--;
|
||||
if(currPoint.x>mControlDimension.width)mStartDisplayColumn++;
|
||||
else if(currPoint.x<xMin)mStartDisplayColumn--;
|
||||
}
|
||||
}
|
||||
//******************************************************************************************************
|
||||
// ******************************************** 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()
|
||||
{
|
||||
}
|
||||
};
|
||||
869
java/SPREAD/HOLD/SPREAD~2.JAV
Normal file
869
java/SPREAD/HOLD/SPREAD~2.JAV
Normal file
@@ -0,0 +1,869 @@
|
||||
/*
|
||||
* @(#)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.lang.*;
|
||||
import java.net.*;
|
||||
|
||||
public class SpreadSheet extends Applet {
|
||||
String title;
|
||||
Font titleFont;
|
||||
Color cellColor;
|
||||
Color inputColor;
|
||||
int cellWidth = 100;
|
||||
int cellHeight = 15;
|
||||
int titleHeight = 15;
|
||||
int rowLabelWidth = 15;
|
||||
Font inputFont;
|
||||
boolean isStopped = false;
|
||||
boolean fullUpdate = true;
|
||||
int rows;
|
||||
int columns;
|
||||
int currentKey = -1;
|
||||
int selectedRow = -1;
|
||||
int selectedColumn = -1;
|
||||
SpreadSheetInput inputArea;
|
||||
Cell cells[][];
|
||||
Cell current = null;
|
||||
|
||||
public synchronized void init() {
|
||||
String rs;
|
||||
|
||||
cellColor = Color.white;
|
||||
inputColor = new Color(100, 100, 225);
|
||||
inputFont = new Font("Courier", Font.PLAIN, 10);
|
||||
titleFont = new Font("Courier", Font.BOLD, 12);
|
||||
title = getParameter("title");
|
||||
if (title == null) {
|
||||
title = "Spreadsheet";
|
||||
}
|
||||
rs = getParameter("rows");
|
||||
if (rs == null) {
|
||||
rows = 9;
|
||||
} else {
|
||||
rows = Integer.parseInt(rs);
|
||||
}
|
||||
rs = getParameter("columns");
|
||||
if (rs == null) {
|
||||
columns = 5;
|
||||
} else {
|
||||
columns = Integer.parseInt(rs);
|
||||
}
|
||||
cells = new Cell[rows][columns];
|
||||
char l[] = new char[1];
|
||||
for (int i=0; i < rows; i++) {
|
||||
for (int j=0; j < columns; j++) {
|
||||
|
||||
cells[i][j] = new Cell(this,
|
||||
Color.lightGray,
|
||||
Color.black,
|
||||
cellColor,
|
||||
cellWidth - 2,
|
||||
cellHeight - 2);
|
||||
l[0] = (char)((int)'a' + j);
|
||||
rs = getParameter("" + new String(l) + (i+1));
|
||||
if (rs != null) {
|
||||
cells[i][j].setUnparsedValue(rs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dimension d = size();
|
||||
inputArea = new SpreadSheetInput(null, this, d.width - 2, cellHeight - 1,
|
||||
inputColor, Color.white);
|
||||
resize(columns * cellWidth + rowLabelWidth,
|
||||
((rows + 1) * cellHeight) + cellHeight + titleHeight);
|
||||
}
|
||||
|
||||
public void setCurrentValue(float val) {
|
||||
if (selectedRow == -1 || selectedColumn == -1) {
|
||||
return;
|
||||
}
|
||||
cells[selectedRow][selectedColumn].setValue(val);
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
isStopped = true;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
isStopped = false;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
for (int i=0; i < rows; i++) {
|
||||
for (int j=0; j < columns; j++) {
|
||||
if (cells[i][j].type == Cell.URL) {
|
||||
cells[i][j].updaterThread.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setCurrentValue(int type, String val) {
|
||||
if (selectedRow == -1 || selectedColumn == -1) {
|
||||
return;
|
||||
}
|
||||
cells[selectedRow][selectedColumn].setValue(type, val);
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void update(Graphics g) {
|
||||
if (! fullUpdate) {
|
||||
int cx, cy;
|
||||
|
||||
g.setFont(titleFont);
|
||||
for (int i=0; i < rows; i++) {
|
||||
for (int j=0; j < columns; j++) {
|
||||
if (cells[i][j].needRedisplay) {
|
||||
cx = (j * cellWidth) + 2 + rowLabelWidth;
|
||||
cy = ((i+1) * cellHeight) + 2 + titleHeight;
|
||||
cells[i][j].paint(g, cx, cy);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
paint(g);
|
||||
fullUpdate = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void recalculate() {
|
||||
int i,j;
|
||||
|
||||
//System.out.println("SpreadSheet.recalculate");
|
||||
for (i=0; i < rows; i++) {
|
||||
for (j=0; j < columns; j++) {
|
||||
if (cells[i][j] != null && cells[i][j].type == Cell.FORMULA) {
|
||||
cells[i][j].setRawValue(evaluateFormula(cells[i][j].parseRoot));
|
||||
cells[i][j].needRedisplay = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
public float evaluateFormula(Node n) {
|
||||
float val = 0.0f;
|
||||
|
||||
//System.out.println("evaluateFormula:");
|
||||
//n.print(3);
|
||||
if (n == null) {
|
||||
//System.out.println("Null node");
|
||||
return val;
|
||||
}
|
||||
switch (n.type) {
|
||||
case Node.OP:
|
||||
val = evaluateFormula(n.left);
|
||||
switch (n.op) {
|
||||
case '+':
|
||||
val += evaluateFormula(n.right);
|
||||
break;
|
||||
case '*':
|
||||
val *= evaluateFormula(n.right);
|
||||
break;
|
||||
case '-':
|
||||
val -= evaluateFormula(n.right);
|
||||
break;
|
||||
case '/':
|
||||
val /= evaluateFormula(n.right);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Node.VALUE:
|
||||
//System.out.println("=>" + n.value);
|
||||
return n.value;
|
||||
case Node.CELL:
|
||||
if (n == null) {
|
||||
//System.out.println("NULL at 192");
|
||||
} else {
|
||||
if (cells[n.row][n.column] == null) {
|
||||
//System.out.println("NULL at 193");
|
||||
} else {
|
||||
//System.out.println("=>" + cells[n.row][n.column].value);
|
||||
return cells[n.row][n.column].value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//System.out.println("=>" + val);
|
||||
return val;
|
||||
}
|
||||
|
||||
public synchronized void paint(Graphics g) {
|
||||
int i, j;
|
||||
int cx, cy;
|
||||
char l[] = new char[1];
|
||||
|
||||
|
||||
Dimension d = size();
|
||||
g.setFont(titleFont);
|
||||
i = g.getFontMetrics().stringWidth(title);
|
||||
g.drawString((title == null) ? "Spreadsheet" : title,
|
||||
(d.width - i) / 2, 12);
|
||||
g.setColor(inputColor);
|
||||
g.fillRect(0, cellHeight, d.width, cellHeight);
|
||||
g.setFont(titleFont);
|
||||
for (i=0; i < rows+1; i++) {
|
||||
cy = (i+2) * cellHeight;
|
||||
g.setColor(getBackground());
|
||||
g.draw3DRect(0, cy, d.width, 2, true);
|
||||
if (i < rows) {
|
||||
g.setColor(Color.red);
|
||||
g.drawString("" + (i+1), 2, cy + 12);
|
||||
}
|
||||
}
|
||||
g.setColor(Color.red);
|
||||
for (i=0; i < columns; i++) {
|
||||
cx = i * cellWidth;
|
||||
g.setColor(getBackground());
|
||||
g.draw3DRect(cx + rowLabelWidth,
|
||||
2 * cellHeight, 1, d.height, true);
|
||||
if (i < columns) {
|
||||
g.setColor(Color.red);
|
||||
l[0] = (char)((int)'A' + i);
|
||||
g.drawString(new String(l),
|
||||
cx + rowLabelWidth + (cellWidth / 2),
|
||||
d.height - 3);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (i=0; i < rows; i++) {
|
||||
for (j=0; j < columns; j++) {
|
||||
cx = (j * cellWidth) + 2 + rowLabelWidth;
|
||||
cy = ((i+1) * cellHeight) + 2 + titleHeight;
|
||||
if (cells[i][j] != null) {
|
||||
cells[i][j].paint(g, cx, cy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g.setColor(getBackground());
|
||||
g.draw3DRect(0, titleHeight,
|
||||
d.width,
|
||||
d.height - titleHeight,
|
||||
false);
|
||||
inputArea.paint(g, 1, titleHeight + 1);
|
||||
}
|
||||
public boolean mouseDown(Event evt, int x, int y)
|
||||
{
|
||||
Cell cell;
|
||||
if (y < (titleHeight + cellHeight))
|
||||
{
|
||||
selectedRow = -1;
|
||||
if (y <= titleHeight && current != null)
|
||||
{
|
||||
current.deselect();
|
||||
current = null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (x < rowLabelWidth)
|
||||
{
|
||||
selectedRow = -1;
|
||||
if (current != null) {
|
||||
current.deselect();
|
||||
current = null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
selectedRow = ((y - cellHeight - titleHeight) / cellHeight);
|
||||
selectedColumn = (x - rowLabelWidth) / cellWidth;
|
||||
if (selectedRow > rows || selectedColumn >= columns)
|
||||
{
|
||||
selectedRow = -1;
|
||||
if(current != null)
|
||||
{
|
||||
current.deselect();
|
||||
current = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selectedRow >= rows)
|
||||
{
|
||||
selectedRow = -1;
|
||||
if (current != null)
|
||||
{
|
||||
current.deselect();
|
||||
current = null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
cell = cells[selectedRow][selectedColumn];
|
||||
|
||||
// inputArea.setText(new String(cell.getPrintString()));
|
||||
// smk
|
||||
if(null!=cell.getPrintString())inputArea.setText(new String(cell.getPrintString()));
|
||||
else inputArea.setText(new String(""));
|
||||
|
||||
if (current != null)current.deselect();
|
||||
current = cell;
|
||||
current.select();
|
||||
requestFocus();
|
||||
fullUpdate = true;
|
||||
repaint();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public boolean keyDown(Event evt, int key)
|
||||
{
|
||||
fullUpdate=true;
|
||||
inputArea.keyDown(key);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class CellUpdater extends Thread {
|
||||
Cell target;
|
||||
InputStream dataStream = null;
|
||||
StreamTokenizer tokenStream;
|
||||
|
||||
public CellUpdater(Cell c) {
|
||||
super("cell updater");
|
||||
target = c;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
dataStream = new URL(target.app.getDocumentBase(),
|
||||
target.getValueString()).openStream();
|
||||
tokenStream = new StreamTokenizer(dataStream);
|
||||
tokenStream.eolIsSignificant(false);
|
||||
|
||||
while (true) {
|
||||
switch (tokenStream.nextToken()) {
|
||||
case tokenStream.TT_EOF:
|
||||
dataStream.close();
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
case tokenStream.TT_NUMBER:
|
||||
target.setTransientValue((float)tokenStream.nval);
|
||||
if (! target.app.isStopped && ! target.paused) {
|
||||
target.app.repaint();
|
||||
}
|
||||
break;
|
||||
}
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch (InterruptedException e) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
Node parseRoot;
|
||||
boolean needRedisplay;
|
||||
boolean selected = false;
|
||||
boolean transientValue = false;
|
||||
public int type = Cell.VALUE;
|
||||
String valueString = "";
|
||||
String printString = "v";
|
||||
float value;
|
||||
Color bgColor;
|
||||
Color fgColor;
|
||||
Color highlightColor;
|
||||
int width;
|
||||
int height;
|
||||
SpreadSheet app;
|
||||
CellUpdater updaterThread;
|
||||
boolean paused = false;
|
||||
|
||||
public Cell(SpreadSheet app,Color bgColor,Color fgColor,Color highlightColor,int width,int height)
|
||||
{
|
||||
this.app = app;
|
||||
this.bgColor = bgColor;
|
||||
this.fgColor = fgColor;
|
||||
this.highlightColor = highlightColor;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
needRedisplay = true;
|
||||
}
|
||||
|
||||
public void setRawValue(float f)
|
||||
{
|
||||
valueString=Float.toString(f);
|
||||
value = f;
|
||||
}
|
||||
public void setValue(float f) {
|
||||
setRawValue(f);
|
||||
printString = "v" + valueString;
|
||||
type = Cell.VALUE;
|
||||
paused = false;
|
||||
app.recalculate();
|
||||
needRedisplay = true;
|
||||
}
|
||||
|
||||
public void setTransientValue(float f) {
|
||||
transientValue = true;
|
||||
value = f;
|
||||
needRedisplay = true;
|
||||
app.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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a spreadsheet formula. The syntax is defined as:
|
||||
*
|
||||
* formula -> value
|
||||
* formula -> value op value
|
||||
* value -> '(' formula ')'
|
||||
* value -> cell
|
||||
* value -> <number>
|
||||
* op -> '+' | '*' | '/' | '-'
|
||||
* cell -> <letter><number>
|
||||
*/
|
||||
public String parseFormula(String formula, Node node) {
|
||||
String subformula;
|
||||
String restFormula;
|
||||
float value;
|
||||
int length = formula.length();
|
||||
Node left;
|
||||
Node right;
|
||||
char op;
|
||||
|
||||
if (formula == null) {
|
||||
return null;
|
||||
}
|
||||
subformula = parseValue(formula, node);
|
||||
//System.out.println("subformula = " + subformula);
|
||||
if (subformula == null || subformula.length() == 0) {
|
||||
//System.out.println("Parse succeeded");
|
||||
return null;
|
||||
}
|
||||
if (subformula == formula) {
|
||||
//System.out.println("Parse failed");
|
||||
return formula;
|
||||
}
|
||||
|
||||
// parse an operator and then another value
|
||||
switch (op = subformula.charAt(0)) {
|
||||
case 0:
|
||||
//System.out.println("Parse succeeded");
|
||||
return null;
|
||||
case ')':
|
||||
//System.out.println("Returning subformula=" + subformula);
|
||||
return subformula;
|
||||
case '+':
|
||||
case '*':
|
||||
case '-':
|
||||
case '/':
|
||||
restFormula = subformula.substring(1);
|
||||
subformula = parseValue(restFormula, right=new Node());
|
||||
//System.out.println("subformula(2) = " + subformula);
|
||||
if (subformula != restFormula) {
|
||||
//System.out.println("Parse succeeded");
|
||||
left = new Node(node);
|
||||
node.left = left;
|
||||
node.right = right;
|
||||
node.op = op;
|
||||
node.type = Node.OP;
|
||||
//node.print(3);
|
||||
return subformula;
|
||||
} else {
|
||||
//System.out.println("Parse failed");
|
||||
return formula;
|
||||
}
|
||||
default:
|
||||
//System.out.println("Parse failed (bad operator): " + subformula);
|
||||
return formula;
|
||||
}
|
||||
}
|
||||
|
||||
public String parseValue(String formula, Node node) {
|
||||
char c = formula.charAt(0);
|
||||
String subformula;
|
||||
String restFormula;
|
||||
float value;
|
||||
int row;
|
||||
int column;
|
||||
|
||||
//System.out.println("parseValue: " + formula);
|
||||
restFormula = formula;
|
||||
if (c == '(') {
|
||||
//System.out.println("parseValue(" + formula + ")");
|
||||
restFormula = formula.substring(1);
|
||||
subformula = parseFormula(restFormula, node);
|
||||
//System.out.println("rest=(" + subformula + ")");
|
||||
if (subformula == null ||
|
||||
subformula.length() == restFormula.length()) {
|
||||
//System.out.println("Failed");
|
||||
return formula;
|
||||
} else if (! (subformula.charAt(0) == ')')) {
|
||||
//System.out.println("Failed (missing parentheses)");
|
||||
return formula;
|
||||
}
|
||||
restFormula = subformula;
|
||||
} else if (c >= '0' && c <= '9') {
|
||||
int i;
|
||||
|
||||
//System.out.println("formula=" + formula);
|
||||
try {
|
||||
value = Float.valueOf(formula).floatValue();
|
||||
} catch (NumberFormatException e) {
|
||||
//System.out.println("Failed (number format error)");
|
||||
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;
|
||||
//node.print(3);
|
||||
restFormula = formula.substring(i);
|
||||
//System.out.println("value= " + value + " i=" + i +
|
||||
// " rest = " + restFormula);
|
||||
return restFormula;
|
||||
} else if (c >= 'A' && c <= 'Z') {
|
||||
int i;
|
||||
|
||||
column = c - 'A';
|
||||
restFormula = formula.substring(1);
|
||||
row = Float.valueOf(restFormula).intValue();
|
||||
//System.out.println("row = " + row + " column = " + column);
|
||||
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;
|
||||
//node.print(3);
|
||||
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) {
|
||||
paused = false;
|
||||
if (this.type == Cell.URL) {
|
||||
updaterThread.stop();
|
||||
updaterThread = null;
|
||||
}
|
||||
|
||||
valueString = new String(s);
|
||||
this.type = type;
|
||||
needRedisplay = true;
|
||||
switch (type) {
|
||||
case Cell.VALUE:
|
||||
setValue(Float.valueOf(s).floatValue());
|
||||
break;
|
||||
case Cell.LABEL:
|
||||
printString = "l" + valueString;
|
||||
break;
|
||||
case Cell.URL:
|
||||
printString = "u" + valueString;
|
||||
updaterThread = new CellUpdater(this);
|
||||
updaterThread.start();
|
||||
break;
|
||||
case Cell.FORMULA:
|
||||
parseFormula(valueString, parseRoot = new Node());
|
||||
printString = "f" + valueString;
|
||||
break;
|
||||
}
|
||||
app.recalculate();
|
||||
}
|
||||
|
||||
public String getValueString() {
|
||||
return valueString;
|
||||
}
|
||||
|
||||
public String getPrintString() {
|
||||
return printString;
|
||||
}
|
||||
|
||||
public void select() {
|
||||
selected = true;
|
||||
paused = true;
|
||||
}
|
||||
public void deselect() {
|
||||
selected = false;
|
||||
paused = false;
|
||||
needRedisplay = true;
|
||||
app.repaint();
|
||||
}
|
||||
public void paint(Graphics g, int x, int y) {
|
||||
if (selected) {
|
||||
g.setColor(highlightColor);
|
||||
} else {
|
||||
g.setColor(bgColor);
|
||||
}
|
||||
g.fillRect(x, y, width - 1, height);
|
||||
if (valueString != null)
|
||||
{
|
||||
switch (type) {
|
||||
case Cell.VALUE:
|
||||
case Cell.LABEL:
|
||||
g.setColor(fgColor);
|
||||
break;
|
||||
case Cell.FORMULA:
|
||||
g.setColor(Color.red);
|
||||
break;
|
||||
case Cell.URL:
|
||||
g.setColor(Color.blue);
|
||||
break;
|
||||
}
|
||||
if (transientValue){
|
||||
g.drawString("" + value, x, y + (height / 2) + 5);
|
||||
} else {
|
||||
if (valueString.length() > 14) {
|
||||
g.drawString(valueString.substring(0, 14),
|
||||
x, y + (height / 2) + 5);
|
||||
} else {
|
||||
g.drawString(valueString, x, y + (height / 2) + 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
needRedisplay = false;
|
||||
}
|
||||
}
|
||||
|
||||
class Node {
|
||||
public static final int OP = 0;
|
||||
public static final int VALUE = 1;
|
||||
public static final int CELL = 2;
|
||||
|
||||
int type;
|
||||
Node left;
|
||||
Node right;
|
||||
int row;
|
||||
int column;
|
||||
float value;
|
||||
char op;
|
||||
|
||||
public Node() {
|
||||
left = null;
|
||||
right = null;
|
||||
value = 0;
|
||||
row = -1;
|
||||
column = -1;
|
||||
op = 0;
|
||||
type = Node.VALUE;
|
||||
}
|
||||
public Node(Node n) {
|
||||
left = n.left;
|
||||
right = n.right;
|
||||
value = n.value;
|
||||
row = n.row;
|
||||
column = n.column;
|
||||
op = n.op;
|
||||
type = n.type;
|
||||
}
|
||||
public void indent(int ind) {
|
||||
for (int i = 0; i < ind; i++) {
|
||||
System.out.print(" ");
|
||||
}
|
||||
}
|
||||
public void print(int indentLevel) {
|
||||
char l[] = new char[1];
|
||||
indent(indentLevel);
|
||||
System.out.println("NODE type=" + type);
|
||||
indent(indentLevel);
|
||||
switch (type) {
|
||||
case Node.VALUE:
|
||||
System.out.println(" value=" + value);
|
||||
break;
|
||||
case Node.CELL:
|
||||
l[0] = (char)((int)'A' + column);
|
||||
System.out.println(" cell=" + new String(l) + (row+1));
|
||||
break;
|
||||
case Node.OP:
|
||||
System.out.println(" op=" + op);
|
||||
left.print(indentLevel + 3);
|
||||
right.print(indentLevel + 3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class InputField
|
||||
{
|
||||
int maxchars = 50;
|
||||
int cursorPos = 0;
|
||||
Applet app;
|
||||
String sval;
|
||||
char buffer[];
|
||||
int nChars;
|
||||
int width;
|
||||
int height;
|
||||
Color bgColor;
|
||||
Color fgColor;
|
||||
|
||||
public InputField(String initValue, Applet app, int width, int height,Color bgColor, Color fgColor) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.bgColor = bgColor;
|
||||
this.fgColor = fgColor;
|
||||
this.app = app;
|
||||
buffer = new char[maxchars];
|
||||
nChars = 0;
|
||||
if (initValue != null) {
|
||||
initValue.getChars(0, initValue.length(), this.buffer, 0);
|
||||
nChars = initValue.length();
|
||||
}
|
||||
sval = initValue;
|
||||
}
|
||||
|
||||
public void setText(String val) {
|
||||
int i;
|
||||
|
||||
for (i=0; i < maxchars; i++) {
|
||||
buffer[i] = 0;
|
||||
}
|
||||
sval = new String(val);
|
||||
if (val == null) {
|
||||
sval = "";
|
||||
nChars = 0;
|
||||
buffer[0] = 0;
|
||||
} else {
|
||||
sval.getChars(0, sval.length(), buffer, 0);
|
||||
nChars = val.length();
|
||||
sval = new String(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return sval;
|
||||
}
|
||||
|
||||
public void paint(Graphics g, int x, int y) {
|
||||
g.setColor(bgColor);
|
||||
g.fillRect(x, y, width, height);
|
||||
if (sval != null) {
|
||||
g.setColor(fgColor);
|
||||
g.drawString(sval, x, y + (height / 2) + 3);
|
||||
}
|
||||
}
|
||||
public void mouseUp(int x, int y) {
|
||||
// set the edit position
|
||||
}
|
||||
public void keyDown(int key) {
|
||||
if (nChars < maxchars) {
|
||||
switch (key) {
|
||||
case 8: // delete
|
||||
--nChars;
|
||||
if (nChars < 0) {
|
||||
nChars = 0;
|
||||
}
|
||||
buffer[nChars] = 0;
|
||||
sval = new String(new String(buffer));
|
||||
break;
|
||||
case 10: // return
|
||||
selected();
|
||||
break;
|
||||
default:
|
||||
buffer[nChars++] = (char)key;
|
||||
sval = new String(new String(buffer));
|
||||
break;
|
||||
}
|
||||
}
|
||||
app.repaint();
|
||||
}
|
||||
public void selected() {
|
||||
}
|
||||
}
|
||||
|
||||
class SpreadSheetInput extends InputField
|
||||
{
|
||||
public SpreadSheetInput(String initValue,SpreadSheet app,int width,int height,Color bgColor,Color fgColor)
|
||||
{
|
||||
super(initValue, app, width, height, bgColor, fgColor);
|
||||
}
|
||||
public void selected()
|
||||
{
|
||||
float f;
|
||||
|
||||
switch (sval.charAt(0))
|
||||
{
|
||||
case 'v':
|
||||
try
|
||||
{
|
||||
f = Float.valueOf(sval.substring(1)).floatValue();
|
||||
((SpreadSheet)app).setCurrentValue(f);
|
||||
}
|
||||
catch(NumberFormatException e){System.out.println("Not a float...");}
|
||||
break;
|
||||
case 'l':
|
||||
((SpreadSheet)app).setCurrentValue(Cell.LABEL, sval.substring(1));
|
||||
break;
|
||||
case 'u':
|
||||
((SpreadSheet)app).setCurrentValue(Cell.URL, sval.substring(1));
|
||||
break;
|
||||
case 'f':
|
||||
((SpreadSheet)app).setCurrentValue(Cell.FORMULA, sval.substring(1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
971
java/SPREAD/HOLD/SPREAD~3.JAV
Normal file
971
java/SPREAD/HOLD/SPREAD~3.JAV
Normal file
@@ -0,0 +1,971 @@
|
||||
|
||||
|
||||
/*
|
||||
* Adapted 10/98 by Sean Kessler
|
||||
* Added arrow key navigation
|
||||
* Added cell scrolling
|
||||
*
|
||||
* @(#)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 SpreadSheet extends Applet
|
||||
{
|
||||
private final Dimension mCellDimension=new Dimension(100,15);
|
||||
private final int mLeftArrow=1006;
|
||||
private final int mRightArrow=1007;
|
||||
private final int mUpArrow=1004;
|
||||
private final int mDownArrow=1005;
|
||||
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;
|
||||
|
||||
public synchronized void init()
|
||||
{
|
||||
String strParam;
|
||||
|
||||
mStartDisplayRow=0;
|
||||
|
||||
mCellColor=Color.white;
|
||||
mInputColor=new Color(100, 100, 225);
|
||||
mTitleFont=new Font("Courier", Font.BOLD, 12);
|
||||
mStrTitle=getParameter("title");
|
||||
if(null==mStrTitle)mStrTitle="SpreadSheet";
|
||||
strParam=getParameter("rows");
|
||||
if(null==strParam)mRows=9;
|
||||
else mRows=Integer.parseInt(strParam);
|
||||
strParam=getParameter("columns");
|
||||
if(null==strParam)mColumns=5;
|
||||
else mColumns=Integer.parseInt(strParam);
|
||||
mCells=new Cell[mRows][mColumns];
|
||||
char strLabel[]=new char[1];
|
||||
for(int i=0; i < mRows; i++)
|
||||
{
|
||||
for (int j=0; j < mColumns; j++)
|
||||
{
|
||||
mCells[i][j]=new Cell(this,Color.lightGray,Color.black,mCellColor,mCellDimension.width-2,mCellDimension.height-2);
|
||||
strLabel[0]=(char)((int)'a'+j);
|
||||
strParam=getParameter(""+new String(strLabel)+(i+1));
|
||||
if(null!=strParam)mCells[i][j].setUnparsedValue(strParam);
|
||||
}
|
||||
}
|
||||
Dimension workArea=size();
|
||||
mInputArea=new SpreadSheetInput(null, this,workArea.width-2,mCellDimension.height-1,mInputColor,Color.white);
|
||||
resize(mColumns*mCellDimension.width+mRowLabelWidth,((mRows+1)*mCellDimension.height)+mCellDimension.height+mTitleHeight);
|
||||
}
|
||||
public void setCurrentValue(float val)
|
||||
{
|
||||
if(-1==mSelectedRow||-1==mSelectedColumn)return;
|
||||
mCells[selectedRow()][mSelectedColumn].setValue(val);
|
||||
// mCells[mSelectedRow][mSelectedColumn].setValue(val);
|
||||
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()
|
||||
{
|
||||
for(int i=0;i<mRows;i++)for(int j=0;j<mColumns;j++)if(mCells[i][j].type()==Cell.URL)mCells[i][j].cellThread().stop();
|
||||
}
|
||||
public void setCurrentValue(int type,String val)
|
||||
{
|
||||
if(-1==mSelectedRow||-1==mSelectedColumn)return;
|
||||
// mCells[mSelectedRow][mSelectedColumn].setValue(type,val);
|
||||
mCells[selectedRow()][mSelectedColumn].setValue(type,val);
|
||||
repaint();
|
||||
}
|
||||
public void update(Graphics graphics)
|
||||
{
|
||||
if(!mFullUpdate)
|
||||
{
|
||||
int cx;
|
||||
int cy;
|
||||
|
||||
graphics.setFont(mTitleFont);
|
||||
// for(int row=0;row<mRows;row++)
|
||||
for(int row=mStartDisplayRow;row<mRows;row++)
|
||||
{
|
||||
for(int col=0;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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
paint(graphics);
|
||||
mFullUpdate = false;
|
||||
}
|
||||
}
|
||||
public synchronized void paint(Graphics graphics)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
int cx;
|
||||
int cy;
|
||||
char strLabel[]=new char[1];
|
||||
|
||||
Dimension clientRect=size();
|
||||
graphics.setFont(mTitleFont);
|
||||
graphics.drawString(mStrTitle,(clientRect.width-graphics.getFontMetrics().stringWidth(mStrTitle))/2,12);
|
||||
graphics.setColor(mInputColor);
|
||||
graphics.fillRect(0,mCellDimension.height,clientRect.width,mCellDimension.height);
|
||||
graphics.setFont(mTitleFont);
|
||||
|
||||
for(i=0;i<mRows+1;i++)
|
||||
{
|
||||
cy=(i+2)*mCellDimension.height;
|
||||
graphics.setColor(getBackground());
|
||||
graphics.draw3DRect(0,cy,clientRect.width,2,true);
|
||||
if(i<mRows)
|
||||
{
|
||||
graphics.setColor(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(getBackground());
|
||||
graphics.draw3DRect(cx+mRowLabelWidth,2*mCellDimension.height,1,clientRect.height,true);
|
||||
}
|
||||
|
||||
for(i=0;i<mRows;i++) // for(i=mStartDisplayRow;i<mRows;i++)
|
||||
{
|
||||
for(j=0;j<mColumns;j++)
|
||||
{
|
||||
cx=(j*mCellDimension.width)+2+mRowLabelWidth;
|
||||
cy=((i+1)*mCellDimension.height)+2+mTitleHeight;
|
||||
if(mCells[i+mStartDisplayRow][j]!=null)mCells[i+mStartDisplayRow][j].paint(graphics,cx,cy);
|
||||
}
|
||||
}
|
||||
|
||||
graphics.setColor(getBackground());
|
||||
graphics.draw3DRect(0,mTitleHeight,clientRect.width,clientRect.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]!=null&&mCells[row+mStartDisplayRow][col].type()==Cell.FORMULA)
|
||||
{
|
||||
mCells[row+mStartDisplayRow][col].setRawValue(evaluateFormula(mCells[row+mStartDisplayRow][col].parseRoot()));
|
||||
mCells[row+mStartDisplayRow][col].needRedisplay(true);
|
||||
}
|
||||
|
||||
// if(mCells[row][col]!=null&&mCells[row][col].type()==Cell.FORMULA)
|
||||
// {
|
||||
// mCells[row][col].setRawValue(evaluateFormula(mCells[row][col].parseRoot()));
|
||||
// mCells[row][col].needRedisplay(true);
|
||||
// }
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
Cell cell;
|
||||
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);
|
||||
mSelectedColumn=(x-mRowLabelWidth)/mCellDimension.width;
|
||||
if(mSelectedRow>mRows||mSelectedColumn>=mColumns)
|
||||
{
|
||||
mSelectedRow = -1;
|
||||
deselect(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mSelectedRow>=mRows)
|
||||
{
|
||||
mSelectedRow = -1;
|
||||
deselect(true);
|
||||
return true;
|
||||
}
|
||||
select();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public boolean keyDown(Event evt, int key)
|
||||
{
|
||||
mFullUpdate=true;
|
||||
if(mLeftArrow==key||mRightArrow==key||mUpArrow==key||mDownArrow==key)navigate(key);
|
||||
else mInputArea.keyDown(key);
|
||||
return true;
|
||||
}
|
||||
private void navigate(int key)
|
||||
{
|
||||
switch(key)
|
||||
{
|
||||
case mLeftArrow :
|
||||
if(mSelectedColumn<=0)break;
|
||||
mSelectedColumn--;
|
||||
select();
|
||||
break;
|
||||
case mRightArrow :
|
||||
if(mSelectedColumn>=mColumns)break;
|
||||
mSelectedColumn++;
|
||||
select();
|
||||
break;
|
||||
case mUpArrow :
|
||||
if(mSelectedRow<=0)break;
|
||||
mSelectedRow--;
|
||||
ensureVisible();
|
||||
select();
|
||||
break;
|
||||
case mDownArrow :
|
||||
if(mSelectedRow+1>=mRows)break;
|
||||
mSelectedRow++;
|
||||
ensureVisible();
|
||||
select();
|
||||
break;
|
||||
}
|
||||
}
|
||||
private int selectedRow()
|
||||
{
|
||||
return mSelectedRow+mStartDisplayRow;
|
||||
}
|
||||
private int selectedColumn()
|
||||
{
|
||||
return mSelectedColumn;
|
||||
}
|
||||
private void select()
|
||||
{
|
||||
Cell cell;
|
||||
|
||||
// String strString="select selRow:"+String.valueOf(mSelectedRow);
|
||||
// showStatus(strString);
|
||||
|
||||
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();
|
||||
requestFocus();
|
||||
mFullUpdate=true;
|
||||
repaint();
|
||||
}
|
||||
private void deselect(boolean destroy)
|
||||
{
|
||||
if(null==mCurrent)return;
|
||||
mCurrent.deselect();
|
||||
if(destroy)mCurrent=null;
|
||||
}
|
||||
|
||||
private boolean ensureVisible()
|
||||
{
|
||||
Point currPoint=new Point(0,0);
|
||||
Dimension workArea=size();
|
||||
boolean adjusted=false;
|
||||
|
||||
// currPoint.y=((mSelectedRow+1)*mCellDimension.height)+2+mTitleHeight;
|
||||
// int firstVisibleRowx=((mStartDisplayRow+2)*mCellDimension.height)+2+mTitleHeight;
|
||||
// int firstVisibleRowx=(2*mCellDimension.height)+2+mTitleHeight;
|
||||
|
||||
int yMin=(2*mCellDimension.height)+2+mTitleHeight;
|
||||
|
||||
currPoint.y=((mSelectedRow-mStartDisplayRow+2)*mCellDimension.height)+2+mTitleHeight;
|
||||
currPoint.x=(mSelectedColumn*mCellDimension.width)+2+mRowLabelWidth;
|
||||
|
||||
String strString=new String(" ");
|
||||
if(currPoint.y>workArea.height)
|
||||
{
|
||||
mStartDisplayRow++;
|
||||
strString+="incrementing startdisplayRow";
|
||||
adjusted=true;
|
||||
}
|
||||
else if(currPoint.y<yMin) // ||currPoint.y<firstVisibleRowx
|
||||
{
|
||||
mStartDisplayRow--;
|
||||
strString+="decrementing startdisplayRow";
|
||||
adjusted=true;
|
||||
}
|
||||
strString+=" (x,y)"+"("+String.valueOf(currPoint.x)+","+String.valueOf(currPoint.y)+")";
|
||||
strString+=" yMin:"+String.valueOf(yMin);
|
||||
showStatus(strString);
|
||||
return adjusted;
|
||||
}
|
||||
}
|
||||
|
||||
//******************************************************************************************************
|
||||
// ***************************************** CELLTHREAD ***********************************************
|
||||
//******************************************************************************************************
|
||||
class CellThread extends Thread
|
||||
{
|
||||
private Cell mTarget;
|
||||
private InputStream mDataStream=null;
|
||||
private StreamTokenizer mTokenStream;
|
||||
|
||||
public CellThread(Cell cell)
|
||||
{
|
||||
super("CellThread");
|
||||
mTarget=cell;
|
||||
}
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
mDataStream = new URL(mTarget.spreadSheet().getDocumentBase(),mTarget.getValueString()).openStream();
|
||||
mTokenStream = new StreamTokenizer(mDataStream);
|
||||
mTokenStream.eolIsSignificant(false);
|
||||
while(true)
|
||||
{
|
||||
switch(mTokenStream.nextToken())
|
||||
{
|
||||
case mTokenStream.TT_EOF:
|
||||
mDataStream.close();
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
case mTokenStream.TT_NUMBER:
|
||||
mTarget.setTransientValue((float)mTokenStream.nval);
|
||||
if(!mTarget.spreadSheet().stopped()&&!mTarget.paused())mTarget.spreadSheet().repaint();
|
||||
break;
|
||||
}
|
||||
try {Thread.sleep(2000);}
|
||||
catch(InterruptedException exception){break;}
|
||||
}
|
||||
}
|
||||
catch (IOException exception){return;}
|
||||
}
|
||||
}
|
||||
//******************************************************************************************************
|
||||
// ******************************************** 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 CellThread mCellThread;
|
||||
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;
|
||||
if(mType == Cell.URL)
|
||||
{
|
||||
mCellThread.stop();
|
||||
mCellThread=null;
|
||||
}
|
||||
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;
|
||||
mCellThread = new CellThread(this);
|
||||
mCellThread.start();
|
||||
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.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-2,mHeight-2);
|
||||
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 CellThread cellThread()
|
||||
{
|
||||
return mCellThread;
|
||||
}
|
||||
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 8: // delete
|
||||
--mChars;
|
||||
if(mChars<0)mChars=0;
|
||||
mBuffer[mChars] = 0;
|
||||
mStringValue = new String(new String(mBuffer));
|
||||
break;
|
||||
case 10: // 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
|
||||
{
|
||||
public SpreadSheetInput(String initValue,SpreadSheet app,int width,int height,Color bgColor,Color fgColor)
|
||||
{
|
||||
super(initValue,app,width,height,bgColor,fgColor);
|
||||
}
|
||||
public void selected()
|
||||
{
|
||||
float f;
|
||||
|
||||
switch(getValue().charAt(0))
|
||||
{
|
||||
case 'v':
|
||||
try{f=Float.valueOf(getValue().substring(1)).floatValue();((SpreadSheet)applet()).setCurrentValue(f);}
|
||||
catch(NumberFormatException exception){;}
|
||||
break;
|
||||
case 'l':
|
||||
((SpreadSheet)applet()).setCurrentValue(Cell.LABEL,getValue().substring(1));
|
||||
break;
|
||||
case 'u':
|
||||
((SpreadSheet)applet()).setCurrentValue(Cell.URL,getValue().substring(1));
|
||||
break;
|
||||
case 'f':
|
||||
((SpreadSheet)applet()).setCurrentValue(Cell.FORMULA,getValue().substring(1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
941
java/SPREAD/HOLD/SPREAD~4.JAV
Normal file
941
java/SPREAD/HOLD/SPREAD~4.JAV
Normal file
@@ -0,0 +1,941 @@
|
||||
/*
|
||||
* 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()
|
||||
{
|
||||
}
|
||||
};
|
||||
933
java/SPREAD/HOLD/SPREAD~5.JAV
Normal file
933
java/SPREAD/HOLD/SPREAD~5.JAV
Normal file
@@ -0,0 +1,933 @@
|
||||
/*
|
||||
* Adapted 10/98 by Sean Kessler
|
||||
* Added arrow key navigation
|
||||
* Added cell scrolling
|
||||
*
|
||||
* @(#)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 SpreadSheet extends Applet
|
||||
public class SpreadSheet
|
||||
{
|
||||
private final Dimension mCellDimension=new Dimension(100,15);
|
||||
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 Applet mApplet;
|
||||
|
||||
public SpreadSheet(Applet applet)
|
||||
{
|
||||
String strParam;
|
||||
|
||||
mApplet=applet;
|
||||
mStartDisplayRow=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 i=0; i < mRows; i++)
|
||||
{
|
||||
for (int j=0; j < mColumns; j++)
|
||||
{
|
||||
mCells[i][j]=new Cell(this,Color.lightGray,Color.black,mCellColor,mCellDimension.width-2,mCellDimension.height-2);
|
||||
strLabel[0]=(char)((int)'a'+j);
|
||||
strParam=mApplet.getParameter(""+new String(strLabel)+(i+1));
|
||||
if(null!=strParam)mCells[i][j].setUnparsedValue(strParam);
|
||||
}
|
||||
}
|
||||
Dimension workArea=mApplet.size();
|
||||
mInputArea=new SpreadSheetInput(null,mApplet,this,workArea.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()
|
||||
{
|
||||
for(int i=0;i<mRows;i++)for(int j=0;j<mColumns;j++)if(mCells[i][j].type()==Cell.URL)mCells[i][j].cellThread().stop();
|
||||
}
|
||||
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=0;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)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
int cx;
|
||||
int cy;
|
||||
char strLabel[]=new char[1];
|
||||
Dimension clientRect=mApplet.size();
|
||||
|
||||
graphics.setFont(mTitleFont);
|
||||
graphics.drawString(mStrTitle,(clientRect.width-graphics.getFontMetrics().stringWidth(mStrTitle))/2,12);
|
||||
graphics.setColor(mInputColor);
|
||||
graphics.fillRect(0,mCellDimension.height,clientRect.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,clientRect.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,clientRect.height,true);
|
||||
}
|
||||
for(i=mStartDisplayRow;i<mRows;i++)
|
||||
{
|
||||
for(j=0;j<mColumns;j++)
|
||||
{
|
||||
cx=(j*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,clientRect.width,clientRect.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]!=null&&mCells[row+mStartDisplayRow][col].type()==Cell.FORMULA)
|
||||
{
|
||||
mCells[row+mStartDisplayRow][col].setRawValue(evaluateFormula(mCells[row+mStartDisplayRow][col].parseRoot()));
|
||||
mCells[row+mStartDisplayRow][col].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--;
|
||||
select();
|
||||
break;
|
||||
case Key.RightArrow :
|
||||
if(mSelectedColumn>=mColumns)break;
|
||||
mSelectedColumn++;
|
||||
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 boolean ensureVisible()
|
||||
{
|
||||
int yMin=(2*mCellDimension.height)+2+mTitleHeight;
|
||||
Point currPoint=new Point(0,0);
|
||||
Dimension workArea=mApplet.size();
|
||||
boolean adjusted=false;
|
||||
|
||||
yMin=(2*mCellDimension.height)+2+mTitleHeight;
|
||||
currPoint.y=((mSelectedRow-mStartDisplayRow+2)*mCellDimension.height)+2+mTitleHeight;
|
||||
currPoint.x=(mSelectedColumn*mCellDimension.width)+2+mRowLabelWidth;
|
||||
if(currPoint.y>workArea.height){mStartDisplayRow++;adjusted=true;}
|
||||
else if(currPoint.y<yMin){mStartDisplayRow--;adjusted=true;}
|
||||
return adjusted;
|
||||
}
|
||||
}
|
||||
|
||||
//******************************************************************************************************
|
||||
// ***************************************** CELLTHREAD ***********************************************
|
||||
//******************************************************************************************************
|
||||
class CellThread extends Thread
|
||||
{
|
||||
private Cell mTarget;
|
||||
private InputStream mDataStream=null;
|
||||
private StreamTokenizer mTokenStream;
|
||||
|
||||
public CellThread(Cell cell)
|
||||
{
|
||||
super("CellThread");
|
||||
mTarget=cell;
|
||||
}
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
mDataStream = new URL(mTarget.spreadSheet().applet().getDocumentBase(),mTarget.getValueString()).openStream();
|
||||
mTokenStream = new StreamTokenizer(mDataStream);
|
||||
mTokenStream.eolIsSignificant(false);
|
||||
while(true)
|
||||
{
|
||||
switch(mTokenStream.nextToken())
|
||||
{
|
||||
case mTokenStream.TT_EOF:
|
||||
mDataStream.close();
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
case mTokenStream.TT_NUMBER:
|
||||
mTarget.setTransientValue((float)mTokenStream.nval);
|
||||
if(!mTarget.spreadSheet().stopped()&&!mTarget.paused())mTarget.spreadSheet().applet().repaint();
|
||||
break;
|
||||
}
|
||||
try {Thread.sleep(2000);}
|
||||
catch(InterruptedException exception){break;}
|
||||
}
|
||||
}
|
||||
catch (IOException exception){return;}
|
||||
}
|
||||
}
|
||||
//******************************************************************************************************
|
||||
// ******************************************** 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 CellThread mCellThread;
|
||||
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;
|
||||
if(mType == Cell.URL)
|
||||
{
|
||||
mCellThread.stop();
|
||||
mCellThread=null;
|
||||
}
|
||||
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;
|
||||
mCellThread = new CellThread(this);
|
||||
mCellThread.start();
|
||||
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 CellThread cellThread()
|
||||
{
|
||||
return mCellThread;
|
||||
}
|
||||
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()
|
||||
{
|
||||
}
|
||||
};
|
||||
876
java/SPREAD/HOLD/SPREAD~6.JAV
Normal file
876
java/SPREAD/HOLD/SPREAD~6.JAV
Normal file
@@ -0,0 +1,876 @@
|
||||
/*
|
||||
* 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 SpreadSheet extends Applet
|
||||
public 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 Applet mApplet;
|
||||
|
||||
public SpreadSheet(Applet applet,Dimension controlDimension)
|
||||
{
|
||||
String strParam;
|
||||
|
||||
mApplet=applet;
|
||||
mControlDimension=controlDimension;
|
||||
mStartDisplayRow=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 i=0; i < mRows; i++)
|
||||
{
|
||||
for (int j=0; j < mColumns; j++)
|
||||
{
|
||||
mCells[i][j]=new Cell(this,Color.lightGray,Color.black,mCellColor,mCellDimension.width-2,mCellDimension.height-2);
|
||||
strLabel[0]=(char)((int)'a'+j);
|
||||
strParam=mApplet.getParameter(""+new String(strLabel)+(i+1));
|
||||
if(null!=strParam)mCells[i][j].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=0;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=0;j<mColumns;j++)
|
||||
{
|
||||
cx=(j*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]!=null&&mCells[row+mStartDisplayRow][col].type()==Cell.FORMULA)
|
||||
{
|
||||
mCells[row+mStartDisplayRow][col].setRawValue(evaluateFormula(mCells[row+mStartDisplayRow][col].parseRoot()));
|
||||
mCells[row+mStartDisplayRow][col].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--;
|
||||
select();
|
||||
break;
|
||||
case Key.RightArrow :
|
||||
if(mSelectedColumn>=mColumns)break;
|
||||
mSelectedColumn++;
|
||||
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;
|
||||
Point currPoint=new Point(0,0);
|
||||
|
||||
yMin=(2*mCellDimension.height)+2+mTitleHeight;
|
||||
currPoint.y=((mSelectedRow-mStartDisplayRow+2)*mCellDimension.height)+2+mTitleHeight;
|
||||
currPoint.x=(mSelectedColumn*mCellDimension.width)+2+mRowLabelWidth;
|
||||
if(currPoint.y>mControlDimension.height)mStartDisplayRow++;
|
||||
else if(currPoint.y<yMin)mStartDisplayRow--;
|
||||
}
|
||||
}
|
||||
|
||||
//******************************************************************************************************
|
||||
// ******************************************** 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()
|
||||
{
|
||||
}
|
||||
};
|
||||
BIN
java/SPREAD/INPUTF~1.CLA
Normal file
BIN
java/SPREAD/INPUTF~1.CLA
Normal file
Binary file not shown.
BIN
java/SPREAD/KEY~1.CLA
Normal file
BIN
java/SPREAD/KEY~1.CLA
Normal file
Binary file not shown.
BIN
java/SPREAD/MONEY~1.CLA
Normal file
BIN
java/SPREAD/MONEY~1.CLA
Normal file
Binary file not shown.
85
java/SPREAD/MONEY~1.JAV
Normal file
85
java/SPREAD/MONEY~1.JAV
Normal file
@@ -0,0 +1,85 @@
|
||||
class Money
|
||||
{
|
||||
private double mValue;
|
||||
public Money()
|
||||
{
|
||||
setValue(0.00);
|
||||
}
|
||||
public Money(double value)
|
||||
{
|
||||
setValue(value);
|
||||
}
|
||||
public Money(Money money)
|
||||
{
|
||||
setValue(money.getValue());
|
||||
}
|
||||
public double getValue()
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
public void setValue(double value)
|
||||
{
|
||||
mValue=value;
|
||||
}
|
||||
public String toString()
|
||||
{
|
||||
String strDouble;
|
||||
String strFixed;
|
||||
String strFinal;
|
||||
String strFraction;
|
||||
int strLength;
|
||||
int commaCount;
|
||||
int initPos;
|
||||
int lastPos;
|
||||
int ptIndex;
|
||||
|
||||
lastPos=0;
|
||||
strFraction=new String();
|
||||
strFinal=new String();
|
||||
strDouble=stringRep(getValue()); // strDouble=String.valueOf(getValue());
|
||||
strLength=strDouble.length();
|
||||
for(ptIndex=0;ptIndex<strLength&&strDouble.charAt(ptIndex)!='.';ptIndex++);
|
||||
if(ptIndex>=strLength)strFraction=".00";
|
||||
else strFraction=strDouble.substring(ptIndex,strLength);
|
||||
if(2==strFraction.length())strFraction+="0";
|
||||
strFixed=strDouble.substring(0,ptIndex);
|
||||
strLength=strFixed.length();
|
||||
initPos=strLength%3;
|
||||
commaCount=strLength/3;
|
||||
if(0==initPos)
|
||||
{
|
||||
initPos+=3;
|
||||
commaCount--;
|
||||
}
|
||||
strFinal+="$";
|
||||
for(int count=0;count<commaCount;count++)
|
||||
{
|
||||
strFinal+=strFixed.substring(lastPos,initPos);
|
||||
strFinal+=",";
|
||||
lastPos=initPos;
|
||||
initPos+=3;
|
||||
}
|
||||
strFinal+=strFixed.substring(lastPos,initPos);
|
||||
strFinal+=strFraction;
|
||||
return strFinal;
|
||||
}
|
||||
private String stringRep(double value)
|
||||
{
|
||||
int ptIndex;
|
||||
int strLength;
|
||||
int strFractionLength;
|
||||
String strRep;
|
||||
String strFraction;
|
||||
String strWhole;
|
||||
|
||||
strRep=String.valueOf(value+.005);
|
||||
strLength=strRep.length();
|
||||
for(ptIndex=0;ptIndex<strLength&&strRep.charAt(ptIndex)!='.';ptIndex++);
|
||||
if(ptIndex>=strLength)return String.valueOf(value);
|
||||
strFraction=strRep.substring(ptIndex+1,strLength);
|
||||
strFractionLength=strFraction.length();
|
||||
if(strFractionLength>2)strFraction=strRep.substring(ptIndex+1,strLength-(strFractionLength-2));
|
||||
strWhole=strRep.substring(0,ptIndex);
|
||||
return strWhole+"."+strFraction;
|
||||
}
|
||||
};
|
||||
BIN
java/SPREAD/NODE~1.CLA
Normal file
BIN
java/SPREAD/NODE~1.CLA
Normal file
Binary file not shown.
11
java/SPREAD/NOTES.TXT
Normal file
11
java/SPREAD/NOTES.TXT
Normal file
@@ -0,0 +1,11 @@
|
||||
//
|
||||
// * Parse a spreadsheet formula. The syntax is defined as:
|
||||
// *
|
||||
// * formula -> value
|
||||
// * formula -> value op value
|
||||
// * value -> '(' formula ')'
|
||||
// * value -> cell
|
||||
// * value -> <number>
|
||||
// * op -> '+' | '*' | '/' | '-'
|
||||
// * cell -> <letter><number>
|
||||
// */
|
||||
BIN
java/SPREAD/PREPAY~1.CLA
Normal file
BIN
java/SPREAD/PREPAY~1.CLA
Normal file
Binary file not shown.
55
java/SPREAD/PREPAY~1.JAV
Normal file
55
java/SPREAD/PREPAY~1.JAV
Normal file
@@ -0,0 +1,55 @@
|
||||
|
||||
public class Prepayment
|
||||
{
|
||||
double mAmount;
|
||||
double mIncrement;
|
||||
double mFrequency;
|
||||
int mPeriod;
|
||||
|
||||
public Prepayment()
|
||||
{
|
||||
mAmount=0.00;
|
||||
mIncrement=0.00;
|
||||
mFrequency=0.00;
|
||||
mPeriod=1;
|
||||
}
|
||||
public Prepayment(double amount,double increment,double frequency)
|
||||
{
|
||||
mAmount=amount;
|
||||
mIncrement=increment;
|
||||
mFrequency=frequency;
|
||||
mPeriod=1;
|
||||
}
|
||||
public double amount()
|
||||
{
|
||||
return mAmount;
|
||||
}
|
||||
public void amount(double amount)
|
||||
{
|
||||
mAmount=amount;
|
||||
}
|
||||
public double increment()
|
||||
{
|
||||
return mIncrement;
|
||||
}
|
||||
public void increment(double increment)
|
||||
{
|
||||
mIncrement=increment;
|
||||
}
|
||||
public double frequency()
|
||||
{
|
||||
return mFrequency;
|
||||
}
|
||||
public void frequency(double frequency)
|
||||
{
|
||||
mFrequency=frequency;
|
||||
}
|
||||
public int period()
|
||||
{
|
||||
return mPeriod;
|
||||
}
|
||||
public void period(int period)
|
||||
{
|
||||
mPeriod=period;
|
||||
}
|
||||
};
|
||||
306
java/SPREAD/PROTO~1.JAV
Normal file
306
java/SPREAD/PROTO~1.JAV
Normal file
@@ -0,0 +1,306 @@
|
||||
import java.awt.*;
|
||||
|
||||
public class Proto extends java.applet.Applet
|
||||
{
|
||||
SpreadSheetInterface mSpreadSheet;
|
||||
PurePassThru mPurePassThru=new PurePassThru();
|
||||
PureCashflow mPureCashflows[];
|
||||
TextField mCtlPrincipal;
|
||||
TextField mCtlInterest;
|
||||
TextField mCtlTerm;
|
||||
|
||||
TextField mCtlPrepayment;
|
||||
TextField mCtlIncrement;
|
||||
TextField mCtlFrequency;
|
||||
Label mCtlCost;
|
||||
|
||||
Button mCtlButton;
|
||||
|
||||
public void init()
|
||||
{
|
||||
performLayout();
|
||||
mSpreadSheet=new SpreadSheetInterface(this,361,10,new Dimension(630,200));
|
||||
mSpreadSheet.setDocumentTitle("Paydown Calculator v1.00");
|
||||
mSpreadSheet.gridLock(true);
|
||||
repaint();
|
||||
}
|
||||
public void update(Graphics graphics)
|
||||
{
|
||||
if(null!=mSpreadSheet)mSpreadSheet.update(graphics);
|
||||
}
|
||||
public void paint(Graphics graphics)
|
||||
{
|
||||
if(null!=mSpreadSheet)mSpreadSheet.paint(graphics);
|
||||
}
|
||||
public boolean mouseDown(Event event,int x,int y)
|
||||
{
|
||||
if(null!=mCtlPrincipal&&mCtlPrincipal==event.target)return false;
|
||||
else if(null!=mCtlInterest&&mCtlInterest==event.target)return false;
|
||||
else if(null!=mCtlTerm&&mCtlTerm==event.target)return false;
|
||||
else if(null!=mCtlButton&&mCtlButton==event.target)return false;
|
||||
else if(null!=mCtlPrepayment&&mCtlPrepayment==event.target)return false;
|
||||
else if(null!=mCtlIncrement&&mCtlIncrement==event.target)return false;
|
||||
else if(null!=mCtlFrequency&&mCtlFrequency==event.target)return false;
|
||||
else if(null!=mSpreadSheet)return mSpreadSheet.mouseDown(event,x,y);
|
||||
return true;
|
||||
}
|
||||
public boolean keyDown(Event event,int key)
|
||||
{
|
||||
if(null!=mCtlPrincipal&&mCtlPrincipal==event.target)return false;
|
||||
else if(null!=mCtlInterest&&mCtlInterest==event.target)return false;
|
||||
else if(null!=mCtlTerm&&mCtlTerm==event.target)return false;
|
||||
else if(null!=mCtlButton&&mCtlButton==event.target)return false;
|
||||
else if(null!=mCtlPrepayment&&mCtlPrepayment==event.target)return false;
|
||||
else if(null!=mCtlIncrement&&mCtlIncrement==event.target)return false;
|
||||
else if(null!=mCtlFrequency&&mCtlFrequency==event.target)return false;
|
||||
else if(null!=mSpreadSheet)return mSpreadSheet.keyDown(event,key);
|
||||
return true;
|
||||
}
|
||||
public void performLayout()
|
||||
{
|
||||
GridBagLayout layout=new GridBagLayout();
|
||||
GridBagConstraints constraints=new GridBagConstraints();
|
||||
setFont(new Font("Fixed",Font.BOLD,12));
|
||||
setLayout(layout);
|
||||
|
||||
constraints.fill=GridBagConstraints.BOTH;
|
||||
constraints.weightx=0.25;
|
||||
Label prnLabel=new Label("Principal",Label.LEFT);
|
||||
layout.setConstraints(prnLabel,constraints);
|
||||
add(prnLabel);
|
||||
mCtlPrincipal=new TextField("$100000.00");
|
||||
layout.setConstraints(mCtlPrincipal,constraints);
|
||||
add(mCtlPrincipal);
|
||||
|
||||
Label intLabel=new Label("Interest",Label.LEFT);
|
||||
layout.setConstraints(intLabel,constraints);
|
||||
add(intLabel);
|
||||
mCtlInterest=new TextField("8.00%");
|
||||
layout.setConstraints(mCtlInterest,constraints);
|
||||
add(mCtlInterest);
|
||||
|
||||
Label trmLabel=new Label("Term",Label.LEFT);
|
||||
layout.setConstraints(trmLabel,constraints);
|
||||
add(trmLabel);
|
||||
mCtlTerm=new TextField("360");
|
||||
layout.setConstraints(mCtlTerm,constraints);
|
||||
add(mCtlTerm);
|
||||
constraints.gridwidth=GridBagConstraints.REMAINDER;
|
||||
mCtlButton=new Button("Calculate");
|
||||
layout.setConstraints(mCtlButton,constraints);
|
||||
add(mCtlButton);
|
||||
|
||||
constraints.fill=GridBagConstraints.BOTH;
|
||||
constraints.gridwidth=1;
|
||||
Label ppyLabel=new Label("Prepayment",Label.LEFT);
|
||||
layout.setConstraints(ppyLabel,constraints);
|
||||
add(ppyLabel);
|
||||
mCtlPrepayment=new TextField("$0.00");
|
||||
layout.setConstraints(mCtlPrepayment,constraints);
|
||||
add(mCtlPrepayment);
|
||||
constraints.gridwidth=GridBagConstraints.REMAINDER;
|
||||
Label ppyHlpLabel=new Label("Enter the amount of your prepayment(s).");
|
||||
layout.setConstraints(ppyHlpLabel,constraints);
|
||||
add(ppyHlpLabel);
|
||||
|
||||
|
||||
|
||||
constraints.fill=GridBagConstraints.BOTH;
|
||||
constraints.gridwidth=1;
|
||||
Label incLabel=new Label("Increment",Label.LEFT);
|
||||
layout.setConstraints(incLabel,constraints);
|
||||
add(incLabel);
|
||||
mCtlIncrement=new TextField("$0.00");
|
||||
layout.setConstraints(mCtlIncrement,constraints);
|
||||
add(mCtlIncrement);
|
||||
constraints.gridwidth=GridBagConstraints.REMAINDER;
|
||||
Label incHlpLabel=new Label("Increment the prepayment(s) by this amount.");
|
||||
layout.setConstraints(incHlpLabel,constraints);
|
||||
add(incHlpLabel);
|
||||
|
||||
|
||||
constraints.fill=GridBagConstraints.BOTH;
|
||||
constraints.gridwidth=1;
|
||||
Label frqLabel=new Label("Frequency",Label.LEFT);
|
||||
layout.setConstraints(frqLabel,constraints);
|
||||
add(frqLabel);
|
||||
mCtlFrequency=new TextField("0.00");
|
||||
layout.setConstraints(mCtlFrequency,constraints);
|
||||
add(mCtlFrequency);
|
||||
constraints.gridwidth=GridBagConstraints.REMAINDER;
|
||||
Label frqHlpLabel=new Label("Frequency at which to increment the prepayments (ie) number of months.");
|
||||
layout.setConstraints(frqHlpLabel,constraints);
|
||||
add(frqHlpLabel);
|
||||
|
||||
constraints.fill=GridBagConstraints.BOTH;
|
||||
constraints.gridwidth=1;
|
||||
Label costLabel=new Label("Cost Of Capital:",Label.LEFT);
|
||||
layout.setConstraints(costLabel,constraints);
|
||||
add(costLabel);
|
||||
mCtlCost=new Label("$0.00",Label.LEFT);
|
||||
constraints.gridwidth=GridBagConstraints.REMAINDER;
|
||||
layout.setConstraints(mCtlCost,constraints);
|
||||
add(mCtlCost);
|
||||
}
|
||||
public boolean action(Event event,Object object)
|
||||
{
|
||||
if(null!=mCtlButton&&mCtlButton==event.target)performCalc();
|
||||
return true;
|
||||
}
|
||||
public void performCalc()
|
||||
{
|
||||
Prepayment prepayment=new Prepayment();
|
||||
String strPrincipal=mCtlPrincipal.getText();
|
||||
String strInterest=mCtlInterest.getText();
|
||||
String strTerm=mCtlTerm.getText();
|
||||
String strPrepayment=mCtlPrepayment.getText();
|
||||
String strIncrement=mCtlIncrement.getText();
|
||||
String strFrequency=mCtlFrequency.getText();
|
||||
Double workDouble;
|
||||
double principal;
|
||||
double interest;
|
||||
int term;
|
||||
int itemIndex;
|
||||
|
||||
workDouble=new Double(0);
|
||||
strPrincipal=strPrincipal.replace('$',' ');
|
||||
workDouble=workDouble.valueOf(strPrincipal);
|
||||
principal=workDouble.doubleValue();
|
||||
strInterest=strInterest.replace('%',' ');
|
||||
workDouble=workDouble.valueOf(strInterest);
|
||||
interest=workDouble.doubleValue();
|
||||
term=Integer.parseInt(strTerm);
|
||||
strPrepayment=strPrepayment.replace('$',' ');
|
||||
workDouble=workDouble.valueOf(strPrepayment);
|
||||
prepayment.amount(workDouble.doubleValue());
|
||||
strIncrement=strIncrement.replace('$',' ');
|
||||
workDouble=workDouble.valueOf(strIncrement);
|
||||
prepayment.increment(workDouble.doubleValue());
|
||||
workDouble=workDouble.valueOf(strFrequency);
|
||||
prepayment.frequency(workDouble.doubleValue());
|
||||
|
||||
mPurePassThru.issBal(principal);
|
||||
mPurePassThru.wac(interest);
|
||||
mPurePassThru.coupon(interest);
|
||||
mPurePassThru.wam((short)term);
|
||||
mPurePassThru.origTerm((short)term);
|
||||
mPurePassThru.psa(0.00);
|
||||
if(0.00!=prepayment.amount()||0.00!=prepayment.increment())generateFlows(prepayment);
|
||||
else generateFlows();
|
||||
Money money=new Money(0);
|
||||
mSpreadSheet.clear();
|
||||
repaint();
|
||||
mSpreadSheet.setCellData(0,0,"BeginBal");
|
||||
mSpreadSheet.setCellData(0,1,"SMM");
|
||||
mSpreadSheet.setCellData(0,2,"MtgPay");
|
||||
mSpreadSheet.setCellData(0,3,"NetIntPay");
|
||||
mSpreadSheet.setCellData(0,4,"GrossIntPay");
|
||||
mSpreadSheet.setCellData(0,5,"SchedPrinPay");
|
||||
mSpreadSheet.setCellData(0,6,"Prepayment");
|
||||
mSpreadSheet.setCellData(0,7,"TotPrin");
|
||||
mSpreadSheet.setCellData(0,8,"Cashflow");
|
||||
mSpreadSheet.setCellData(0,9,"Factor");
|
||||
|
||||
for(itemIndex=0;itemIndex<mPurePassThru.wam();itemIndex++)
|
||||
{
|
||||
if(mPureCashflows[itemIndex]==null)break;
|
||||
money.setValue(mPureCashflows[itemIndex].beginBal());
|
||||
mSpreadSheet.setCellData(itemIndex+1,0,money.toString());
|
||||
money.setValue(mPureCashflows[itemIndex].smm());
|
||||
mSpreadSheet.setCellData(itemIndex+1,1,money.toString());
|
||||
money.setValue(mPureCashflows[itemIndex].mtgPay());
|
||||
mSpreadSheet.setCellData(itemIndex+1,2,money.toString());
|
||||
money.setValue(mPureCashflows[itemIndex].netIntPay());
|
||||
mSpreadSheet.setCellData(itemIndex+1,3,money.toString());
|
||||
money.setValue(mPureCashflows[itemIndex].grossIntPay());
|
||||
mSpreadSheet.setCellData(itemIndex+1,4,money.toString());
|
||||
money.setValue(mPureCashflows[itemIndex].schedPrinPay());
|
||||
mSpreadSheet.setCellData(itemIndex+1,5,money.toString());
|
||||
money.setValue(mPureCashflows[itemIndex].prepayment());
|
||||
mSpreadSheet.setCellData(itemIndex+1,6,money.toString());
|
||||
money.setValue(mPureCashflows[itemIndex].totPrin());
|
||||
mSpreadSheet.setCellData(itemIndex+1,7,money.toString());
|
||||
money.setValue(mPureCashflows[itemIndex].cashflow());
|
||||
mSpreadSheet.setCellData(itemIndex+1,8,money.toString());
|
||||
mSpreadSheet.setCellData(itemIndex+1,9,String.valueOf(mPureCashflows[itemIndex].factor()));
|
||||
}
|
||||
money.setValue(mPureCashflows[itemIndex-1].grossIntPay());
|
||||
mCtlCost.setText(money.toString());
|
||||
repaint();
|
||||
}
|
||||
public void generateFlows()
|
||||
{
|
||||
double issBal;
|
||||
double tmpCPR;
|
||||
int actualMonth;
|
||||
int indexFlows;
|
||||
|
||||
indexFlows=0;
|
||||
mPureCashflows=new PureCashflow[mPurePassThru.wam()];
|
||||
issBal=mPurePassThru.issBal();
|
||||
for(int wam=mPurePassThru.wam();wam>0&&issBal>0.00;wam--)
|
||||
{
|
||||
mPureCashflows[indexFlows]=new PureCashflow();
|
||||
actualMonth=(mPurePassThru.origTerm()-wam)+1;
|
||||
if(actualMonth<=30)tmpCPR=.002*(double)actualMonth;
|
||||
else tmpCPR=.06;
|
||||
mPureCashflows[indexFlows].beginBal(issBal);
|
||||
mPureCashflows[indexFlows].smm(1.00-Math.pow(1.00-(tmpCPR*mPurePassThru.psa()/100.00),1.00/12.00));
|
||||
if(0==indexFlows)mPureCashflows[indexFlows].mtgPay((issBal*(mPurePassThru.wac()/1200.00))/
|
||||
(1.00-Math.pow(1.00/(1.00+(mPurePassThru.wac()/1200.00)),(double)wam)));
|
||||
else mPureCashflows[indexFlows].mtgPay(mPureCashflows[indexFlows-1].mtgPay());
|
||||
if(issBal<=mPureCashflows[indexFlows].mtgPay())mPureCashflows[indexFlows].mtgPay(issBal);
|
||||
mPureCashflows[indexFlows].netIntPay(issBal*(mPurePassThru.coupon()/1200.00));
|
||||
if(0==indexFlows)mPureCashflows[indexFlows].grossIntPay(mPureCashflows[indexFlows].netIntPay());
|
||||
else mPureCashflows[indexFlows].grossIntPay(mPureCashflows[indexFlows-1].grossIntPay()+mPureCashflows[indexFlows].netIntPay());
|
||||
mPureCashflows[indexFlows].schedPrinPay(mPureCashflows[indexFlows].mtgPay()-mPureCashflows[indexFlows].netIntPay());
|
||||
mPureCashflows[indexFlows].prepayment(0.00);
|
||||
mPureCashflows[indexFlows].totPrin(mPureCashflows[indexFlows].schedPrinPay()+mPureCashflows[indexFlows].prepayment());
|
||||
mPureCashflows[indexFlows].cashflow(mPureCashflows[indexFlows].netIntPay()+mPureCashflows[indexFlows].totPrin());
|
||||
mPureCashflows[indexFlows].factor(issBal/mPurePassThru.issBal());
|
||||
issBal-=mPureCashflows[indexFlows].totPrin();
|
||||
indexFlows++;
|
||||
}
|
||||
}
|
||||
public void generateFlows(Prepayment prepayment)
|
||||
{
|
||||
double issBal;
|
||||
double tmpCPR;
|
||||
int actualMonth;
|
||||
int indexFlows;
|
||||
|
||||
indexFlows=0;
|
||||
mPureCashflows=new PureCashflow[mPurePassThru.wam()];
|
||||
issBal=mPurePassThru.issBal();
|
||||
for(int wam=mPurePassThru.wam();wam>0&&issBal>0.00;wam--)
|
||||
{
|
||||
mPureCashflows[indexFlows]=new PureCashflow();
|
||||
actualMonth=(mPurePassThru.origTerm()-wam)+1;
|
||||
if(actualMonth<=30)tmpCPR=.002*(double)actualMonth;
|
||||
else tmpCPR=.06;
|
||||
mPureCashflows[indexFlows].beginBal(issBal);
|
||||
mPureCashflows[indexFlows].smm(1.00-Math.pow(1.00-(tmpCPR*mPurePassThru.psa()/100.00),1.00/12.00));
|
||||
if(0==indexFlows)mPureCashflows[indexFlows].mtgPay((issBal*(mPurePassThru.wac()/1200.00))/
|
||||
(1.00-Math.pow(1.00/(1.00+(mPurePassThru.wac()/1200.00)),(double)wam)));
|
||||
else mPureCashflows[indexFlows].mtgPay(mPureCashflows[indexFlows-1].mtgPay());
|
||||
if(issBal<=mPureCashflows[indexFlows].mtgPay())mPureCashflows[indexFlows].mtgPay(issBal);
|
||||
mPureCashflows[indexFlows].netIntPay(issBal*(mPurePassThru.coupon()/1200.00));
|
||||
if(0==indexFlows)mPureCashflows[indexFlows].grossIntPay(mPureCashflows[indexFlows].netIntPay());
|
||||
else mPureCashflows[indexFlows].grossIntPay(mPureCashflows[indexFlows-1].grossIntPay()+mPureCashflows[indexFlows].netIntPay());
|
||||
mPureCashflows[indexFlows].schedPrinPay(mPureCashflows[indexFlows].mtgPay()-mPureCashflows[indexFlows].netIntPay());
|
||||
mPureCashflows[indexFlows].prepayment(prepayment.amount());
|
||||
prepayment.period(prepayment.period()+1);
|
||||
if(prepayment.period()>prepayment.frequency())
|
||||
{
|
||||
prepayment.amount(prepayment.amount()+prepayment.increment());
|
||||
prepayment.period(1);
|
||||
}
|
||||
mPureCashflows[indexFlows].totPrin(mPureCashflows[indexFlows].schedPrinPay()+mPureCashflows[indexFlows].prepayment());
|
||||
mPureCashflows[indexFlows].cashflow(mPureCashflows[indexFlows].netIntPay()+mPureCashflows[indexFlows].totPrin());
|
||||
mPureCashflows[indexFlows].factor(issBal/mPurePassThru.issBal());
|
||||
issBal-=mPureCashflows[indexFlows].totPrin();
|
||||
indexFlows++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIN
java/SPREAD/PURECA~1.CLA
Normal file
BIN
java/SPREAD/PURECA~1.CLA
Normal file
Binary file not shown.
140
java/SPREAD/PURECA~1.JAV
Normal file
140
java/SPREAD/PURECA~1.JAV
Normal file
@@ -0,0 +1,140 @@
|
||||
|
||||
class PureCashflow
|
||||
{
|
||||
double mBeginBal;
|
||||
double mSMM;
|
||||
double mMtgPay;
|
||||
double mNetIntPay;
|
||||
double mGrossIntPay;
|
||||
double mSchedPrinPay;
|
||||
double mPrepayment;
|
||||
double mTotPrin;
|
||||
double mCashFlow;
|
||||
double mFactor;
|
||||
|
||||
public PureCashflow()
|
||||
{
|
||||
mBeginBal=0.00;
|
||||
mSMM=0.00;
|
||||
mMtgPay=0.00;
|
||||
mNetIntPay=0.00;
|
||||
mGrossIntPay=0.00;
|
||||
mSchedPrinPay=0.00;
|
||||
mPrepayment=0.00;
|
||||
mTotPrin=0.00;
|
||||
mCashFlow=0.00;
|
||||
mFactor=0.00;
|
||||
}
|
||||
public PureCashflow(PureCashflow pureCashflow)
|
||||
{
|
||||
beginBal(pureCashflow.beginBal());
|
||||
smm(pureCashflow.smm());
|
||||
mtgPay(pureCashflow.mtgPay());
|
||||
netIntPay(pureCashflow.netIntPay());
|
||||
grossIntPay(pureCashflow.grossIntPay());
|
||||
schedPrinPay(pureCashflow.schedPrinPay());
|
||||
prepayment(pureCashflow.prepayment());
|
||||
totPrin(pureCashflow.totPrin());
|
||||
cashflow(pureCashflow.cashflow());
|
||||
factor(pureCashflow.factor());
|
||||
}
|
||||
public double beginBal()
|
||||
{
|
||||
return mBeginBal;
|
||||
}
|
||||
public void beginBal(double beginBal)
|
||||
{
|
||||
mBeginBal=beginBal;
|
||||
}
|
||||
public double smm()
|
||||
{
|
||||
return mSMM;
|
||||
}
|
||||
public void smm(double smm)
|
||||
{
|
||||
mSMM=smm;
|
||||
}
|
||||
public double mtgPay()
|
||||
{
|
||||
return mMtgPay;
|
||||
}
|
||||
public void mtgPay(double mtgPay)
|
||||
{
|
||||
mMtgPay=mtgPay;
|
||||
}
|
||||
public double netIntPay()
|
||||
{
|
||||
return mNetIntPay;
|
||||
}
|
||||
public void netIntPay(double netIntPay)
|
||||
{
|
||||
mNetIntPay=netIntPay;
|
||||
}
|
||||
public double grossIntPay()
|
||||
{
|
||||
return mGrossIntPay;
|
||||
}
|
||||
public void grossIntPay(double grossIntPay)
|
||||
{
|
||||
mGrossIntPay=grossIntPay;
|
||||
}
|
||||
public double schedPrinPay()
|
||||
{
|
||||
return mSchedPrinPay;
|
||||
}
|
||||
public void schedPrinPay(double schedPrinPay)
|
||||
{
|
||||
mSchedPrinPay=schedPrinPay;
|
||||
}
|
||||
public double prepayment()
|
||||
{
|
||||
return mPrepayment;
|
||||
}
|
||||
public void prepayment(double prepayment)
|
||||
{
|
||||
mPrepayment=prepayment;
|
||||
}
|
||||
public double totPrin()
|
||||
{
|
||||
return mTotPrin;
|
||||
}
|
||||
public void totPrin(double totPrin)
|
||||
{
|
||||
mTotPrin=totPrin;
|
||||
}
|
||||
public double cashflow()
|
||||
{
|
||||
return mCashFlow;
|
||||
}
|
||||
public void cashflow(double cashFlow)
|
||||
{
|
||||
mCashFlow=cashFlow;
|
||||
}
|
||||
public double factor()
|
||||
{
|
||||
return mFactor;
|
||||
}
|
||||
public void factor(double factor)
|
||||
{
|
||||
mFactor=factor;
|
||||
}
|
||||
public String toString()
|
||||
{
|
||||
String strReturn;
|
||||
Money money;
|
||||
|
||||
strReturn=new String();
|
||||
money=new Money();
|
||||
strReturn+=(new Money(beginBal())).toString();
|
||||
// strReturn+=(new Money(smm())).toString();
|
||||
strReturn+=(new Money(mtgPay())).toString();
|
||||
strReturn+=(new Money(netIntPay())).toString();
|
||||
strReturn+=(new Money(grossIntPay())).toString();
|
||||
strReturn+=(new Money(schedPrinPay())).toString();
|
||||
strReturn+=(new Money(prepayment())).toString();
|
||||
strReturn+=(new Money(totPrin())).toString();
|
||||
strReturn+=(new Money(cashflow())).toString()+" ";
|
||||
// strReturn+=String.valueOf(factor());
|
||||
return strReturn;
|
||||
}
|
||||
}
|
||||
BIN
java/SPREAD/PUREPA~1.CLA
Normal file
BIN
java/SPREAD/PUREPA~1.CLA
Normal file
Binary file not shown.
86
java/SPREAD/PUREPA~1.JAV
Normal file
86
java/SPREAD/PUREPA~1.JAV
Normal file
@@ -0,0 +1,86 @@
|
||||
class PurePassThru
|
||||
{
|
||||
int mSanity;
|
||||
double mIssBal;
|
||||
double mWAC;
|
||||
double mCoupon;
|
||||
short mWAM;
|
||||
short mOrigTerm;
|
||||
double mPSA;
|
||||
public PurePassThru()
|
||||
{
|
||||
mSanity=0;
|
||||
mIssBal=0.00;
|
||||
mWAC=0.00;
|
||||
mCoupon=0.00;
|
||||
mWAM=0;
|
||||
mOrigTerm=0;
|
||||
mPSA=0.00;
|
||||
}
|
||||
public PurePassThru(PurePassThru purePassThru)
|
||||
{
|
||||
sanity(purePassThru.sanity());
|
||||
issBal(purePassThru.issBal());
|
||||
wac(purePassThru.wac());
|
||||
coupon(purePassThru.coupon());
|
||||
wam(purePassThru.wam());
|
||||
origTerm(purePassThru.origTerm());
|
||||
psa(purePassThru.psa());
|
||||
}
|
||||
public int sanity()
|
||||
{
|
||||
return mSanity;
|
||||
}
|
||||
public void sanity(int sanity)
|
||||
{
|
||||
mSanity=sanity;
|
||||
}
|
||||
public double issBal()
|
||||
{
|
||||
return mIssBal;
|
||||
}
|
||||
public void issBal(double issBal)
|
||||
{
|
||||
mIssBal=issBal;
|
||||
}
|
||||
public double wac()
|
||||
{
|
||||
return mWAC;
|
||||
}
|
||||
public void wac(double wac)
|
||||
{
|
||||
mWAC=wac;
|
||||
}
|
||||
public double coupon()
|
||||
{
|
||||
return mCoupon;
|
||||
}
|
||||
public void coupon(double coupon)
|
||||
{
|
||||
mCoupon=coupon;
|
||||
}
|
||||
public short wam()
|
||||
{
|
||||
return mWAM;
|
||||
}
|
||||
public void wam(short wam)
|
||||
{
|
||||
mWAM=wam;
|
||||
}
|
||||
public short origTerm()
|
||||
{
|
||||
return mOrigTerm;
|
||||
}
|
||||
public void origTerm(short origTerm)
|
||||
{
|
||||
mOrigTerm=origTerm;
|
||||
}
|
||||
public double psa()
|
||||
{
|
||||
return mPSA;
|
||||
}
|
||||
public void psa(double psa)
|
||||
{
|
||||
mPSA=psa;
|
||||
}
|
||||
}
|
||||
293
java/SPREAD/SCRAPS.TXT
Normal file
293
java/SPREAD/SCRAPS.TXT
Normal file
@@ -0,0 +1,293 @@
|
||||
// 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();
|
||||
// requestFocus();
|
||||
// mFullUpdate = true;
|
||||
// repaint();
|
||||
|
||||
|
||||
// graphics.fillRect(x,y,mWidth-1,mHeight);
|
||||
|
||||
|
||||
if(mTransientValue)graphics.drawString("" + mValue,x,y+(mHeight/2)+5);
|
||||
else
|
||||
{
|
||||
if(mValueString.length() > 14)graphics.drawString(mValueString.substring(0,14),x,y+(mHeight/2)+5);
|
||||
else graphics.drawString(mValueString,x,y+(mHeight/2)+5);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public synchronized void paint(Graphics graphics)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
int cx;
|
||||
int cy;
|
||||
char strLabel[]=new char[1];
|
||||
|
||||
Dimension clientRect=size();
|
||||
graphics.setFont(mTitleFont);
|
||||
graphics.drawString(mStrTitle,(clientRect.width-graphics.getFontMetrics().stringWidth(mStrTitle))/2,12);
|
||||
graphics.setColor(mInputColor);
|
||||
graphics.fillRect(0,mCellDimension.height,clientRect.width,mCellDimension.height);
|
||||
graphics.setFont(mTitleFont);
|
||||
for(i=0;i<mRows+1;i++)
|
||||
// for(i=mStartDisplayRow;i<mRows;i++)
|
||||
{
|
||||
cy=(i+2)*mCellDimension.height;
|
||||
graphics.setColor(getBackground());
|
||||
graphics.draw3DRect(0,cy,clientRect.width,2,true);
|
||||
if(i<mRows)
|
||||
{
|
||||
// graphics.setColor(Color.red);
|
||||
// graphics.drawString(""+(i+1),2,cy+12);
|
||||
|
||||
|
||||
graphics.setColor(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(getBackground());
|
||||
graphics.draw3DRect(cx+mRowLabelWidth,2*mCellDimension.height,1,clientRect.height,true);
|
||||
|
||||
// if(i<mColumns)
|
||||
// {
|
||||
// graphics.setColor(Color.red);
|
||||
// strLabel[0]=(char)((int)'A'+i);
|
||||
// l[0]=(char)((int)'A'+i);
|
||||
// graphics.drawString(new String(strLabel),cx+mRowLabelWidth+(mCellDimension.width/2),clientRect.height-3);
|
||||
// }
|
||||
}
|
||||
|
||||
for(i=0;i<mRows;i++) // for(i=mStartDisplayRow;i<mRows;i++)
|
||||
{
|
||||
for(j=0;j<mColumns;j++)
|
||||
{
|
||||
cx=(j*mCellDimension.width)+2+mRowLabelWidth;
|
||||
cy=((i+1)*mCellDimension.height)+2+mTitleHeight;
|
||||
if(mCells[i+mStartDisplayRow][j]!=null)mCells[i+mStartDisplayRow][j].paint(graphics,cx,cy);
|
||||
}
|
||||
}
|
||||
|
||||
graphics.setColor(getBackground());
|
||||
graphics.draw3DRect(0,mTitleHeight,clientRect.width,clientRect.height-mTitleHeight,false);
|
||||
mInputArea.paint(graphics,1,mTitleHeight+1);
|
||||
|
||||
}
|
||||
-c
|
||||
|
||||
|
||||
graphics.setColor(Color.red);
|
||||
for(i=0;i<mColumns;i++)
|
||||
{
|
||||
cx=i*mCellDimension.width;
|
||||
graphics.setColor(getBackground());
|
||||
graphics.draw3DRect(cx+mRowLabelWidth,2*mCellDimension.height,1,clientRect.height,true);
|
||||
|
||||
// if(i<mColumns)
|
||||
// {
|
||||
// graphics.setColor(Color.red);
|
||||
// strLabel[0]=(char)((int)'A'+i);
|
||||
// l[0]=(char)((int)'A'+i);
|
||||
// graphics.drawString(new String(strLabel),cx+mRowLabelWidth+(mCellDimension.width/2),clientRect.height-3);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
// for(i=0;i<mRows;i++) // for(i=mStartDisplayRow;i<mRows;i++)
|
||||
// {
|
||||
// for(j=0;j<mColumns;j++)
|
||||
// {
|
||||
// cx=(j*mCellDimension.width)+2+mRowLabelWidth;
|
||||
// cy=((i+1)*mCellDimension.height)+2+mTitleHeight;
|
||||
// if(mCells[i+mStartDisplayRow][j]!=null)mCells[i+mStartDisplayRow][j].paint(graphics,cx,cy);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
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-2,mHeight-2);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//******************************************************************************************************
|
||||
// ***************************************** CELLTHREAD ***********************************************
|
||||
//******************************************************************************************************
|
||||
class CellThread extends Thread
|
||||
{
|
||||
private Cell mTarget;
|
||||
private InputStream mDataStream=null;
|
||||
private StreamTokenizer mTokenStream;
|
||||
|
||||
public CellThread(Cell cell)
|
||||
{
|
||||
super("CellThread");
|
||||
mTarget=cell;
|
||||
}
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
mDataStream = new URL(mTarget.spreadSheet().applet().getDocumentBase(),mTarget.getValueString()).openStream();
|
||||
mTokenStream = new StreamTokenizer(mDataStream);
|
||||
mTokenStream.eolIsSignificant(false);
|
||||
while(true)
|
||||
{
|
||||
switch(mTokenStream.nextToken())
|
||||
{
|
||||
case mTokenStream.TT_EOF:
|
||||
mDataStream.close();
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
case mTokenStream.TT_NUMBER:
|
||||
mTarget.setTransientValue((float)mTokenStream.nval);
|
||||
if(!mTarget.spreadSheet().stopped()&&!mTarget.paused())mTarget.spreadSheet().applet().repaint();
|
||||
break;
|
||||
}
|
||||
try {Thread.sleep(2000);}
|
||||
catch(InterruptedException exception){break;}
|
||||
}
|
||||
}
|
||||
catch (IOException exception){return;}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if(mType == Cell.URL)
|
||||
// {
|
||||
// mCellThread.stop();
|
||||
// mCellThread=null;
|
||||
// }
|
||||
|
||||
|
||||
// mCellThread = new CellThread(this);
|
||||
// mCellThread.start();
|
||||
|
||||
|
||||
// public CellThread cellThread()
|
||||
// {
|
||||
// return mCellThread;
|
||||
// }
|
||||
|
||||
|
||||
//import java.awt.Font;
|
||||
//import java.awt.Graphics;
|
||||
//import java.awt.Color;
|
||||
//import java.util.Date;
|
||||
//import java.awt.Frame;
|
||||
//import java.awt.image.*;
|
||||
|
||||
//import java.applet.*;
|
||||
//import java.util.*;
|
||||
//import java.net.*;
|
||||
|
||||
|
||||
|
||||
|
||||
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);
|
||||
// drawGrid(graphics);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 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);
|
||||
//
|
||||
// String printString;
|
||||
// if(mValueString.length()>14)printString=new String(mValueString.substring(0,14));
|
||||
// else printString=mValueString;
|
||||
// FontMetrics metrics=graphics.getFontMetrics();
|
||||
// int stringWidth=metrics.stringWidth(printString);
|
||||
// if(x+stringWidth<mSpreadSheet.controlDimension().width)graphics.drawString(printString,x,y+(mHeight/2)+5);
|
||||
//
|
||||
// }
|
||||
// else graphics.drawString(""+mValue,x,y+(mHeight/2)+5);
|
||||
|
||||
public void setText(String val)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(val==null)
|
||||
{
|
||||
mStringValue=new String("");
|
||||
mChars=0;
|
||||
mBuffer[0]=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i=0;i<mMaxChars;i++)mBuffer[i]=0;
|
||||
mStringValue=new String(val);
|
||||
mStringValue.getChars(0,mStringValue.length(),mBuffer,0);
|
||||
// mChars=val.length();
|
||||
// mStringValue=new String(mBuffer);
|
||||
for(i=0;mBuffer[i]!=0&&i<mMaxChars;i++);
|
||||
mChars=i;
|
||||
mStringValue=new String(mBuffer).substring(0,i);
|
||||
}
|
||||
}
|
||||
288
java/SPREAD/SPREAD.MAK
Normal file
288
java/SPREAD/SPREAD.MAK
Normal file
@@ -0,0 +1,288 @@
|
||||
# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Java Virtual Machine Java Workspace" 0x0809
|
||||
|
||||
!IF "$(CFG)" == ""
|
||||
CFG=spread - Java Virtual Machine Debug
|
||||
!MESSAGE No configuration specified. Defaulting to spread - Java Virtual\
|
||||
Machine Debug.
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" != "spread - Java Virtual Machine Release" && "$(CFG)" !=\
|
||||
"spread - Java Virtual Machine Debug"
|
||||
!MESSAGE Invalid configuration "$(CFG)" specified.
|
||||
!MESSAGE You can specify a configuration when running NMAKE on this makefile
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "spread.mak" CFG="spread - Java Virtual Machine Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "spread - Java Virtual Machine Release" (based on\
|
||||
"Java Virtual Machine Java Workspace")
|
||||
!MESSAGE "spread - Java Virtual Machine Debug" (based on\
|
||||
"Java Virtual Machine Java Workspace")
|
||||
!MESSAGE
|
||||
!ERROR An invalid configuration is specified.
|
||||
!ENDIF
|
||||
|
||||
!IF "$(OS)" == "Windows_NT"
|
||||
NULL=
|
||||
!ELSE
|
||||
NULL=nul
|
||||
!ENDIF
|
||||
################################################################################
|
||||
# Begin Project
|
||||
# PROP Target_Last_Scanned "spread - Java Virtual Machine Debug"
|
||||
JAVA=jvc.exe
|
||||
|
||||
!IF "$(CFG)" == "spread - Java Virtual Machine Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir ""
|
||||
# PROP BASE Intermediate_Dir ""
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir ""
|
||||
# PROP Intermediate_Dir ""
|
||||
# PROP Target_Dir ""
|
||||
OUTDIR=.
|
||||
INTDIR=.
|
||||
|
||||
ALL : "$(OUTDIR)\Key.class" "$(OUTDIR)\SpreadSheetInput.class"\
|
||||
"$(OUTDIR)\InputField.class" "$(OUTDIR)\Node.class" "$(OUTDIR)\Cell.class"\
|
||||
"$(OUTDIR)\SpreadSheet.class" "$(OUTDIR)\SpreadSheetInterface.class"\
|
||||
"$(OUTDIR)\PurePassThru.class" "$(OUTDIR)\PureCashflow.class"\
|
||||
"$(OUTDIR)\Money.class" "$(OUTDIR)\Prepayment.class" "$(OUTDIR)\Proto.class"
|
||||
|
||||
CLEAN :
|
||||
-@erase "$(INTDIR)\Cell.class"
|
||||
-@erase "$(INTDIR)\InputField.class"
|
||||
-@erase "$(INTDIR)\Key.class"
|
||||
-@erase "$(INTDIR)\Money.class"
|
||||
-@erase "$(INTDIR)\Node.class"
|
||||
-@erase "$(INTDIR)\Prepayment.class"
|
||||
-@erase "$(INTDIR)\Proto.class"
|
||||
-@erase "$(INTDIR)\PureCashflow.class"
|
||||
-@erase "$(INTDIR)\PurePassThru.class"
|
||||
-@erase "$(INTDIR)\SpreadSheet.class"
|
||||
-@erase "$(INTDIR)\SpreadSheetInput.class"
|
||||
-@erase "$(INTDIR)\SpreadSheetInterface.class"
|
||||
|
||||
# ADD BASE JAVA /O
|
||||
# ADD JAVA /O
|
||||
|
||||
!ELSEIF "$(CFG)" == "spread - Java Virtual Machine Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir ""
|
||||
# PROP BASE Intermediate_Dir ""
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir ""
|
||||
# PROP Intermediate_Dir ""
|
||||
# PROP Target_Dir ""
|
||||
OUTDIR=.
|
||||
INTDIR=.
|
||||
|
||||
ALL : "$(OUTDIR)\Key.class" "$(OUTDIR)\SpreadSheetInput.class"\
|
||||
"$(OUTDIR)\InputField.class" "$(OUTDIR)\Node.class" "$(OUTDIR)\Cell.class"\
|
||||
"$(OUTDIR)\SpreadSheet.class" "$(OUTDIR)\SpreadSheetInterface.class"\
|
||||
"$(OUTDIR)\PurePassThru.class" "$(OUTDIR)\PureCashflow.class"\
|
||||
"$(OUTDIR)\Money.class" "$(OUTDIR)\Prepayment.class" "$(OUTDIR)\Cashflow.class"
|
||||
|
||||
CLEAN :
|
||||
-@erase "$(INTDIR)\Cashflow.class"
|
||||
-@erase "$(INTDIR)\Cell.class"
|
||||
-@erase "$(INTDIR)\InputField.class"
|
||||
-@erase "$(INTDIR)\Key.class"
|
||||
-@erase "$(INTDIR)\Money.class"
|
||||
-@erase "$(INTDIR)\Node.class"
|
||||
-@erase "$(INTDIR)\Prepayment.class"
|
||||
-@erase "$(INTDIR)\PureCashflow.class"
|
||||
-@erase "$(INTDIR)\PurePassThru.class"
|
||||
-@erase "$(INTDIR)\SpreadSheet.class"
|
||||
-@erase "$(INTDIR)\SpreadSheetInput.class"
|
||||
-@erase "$(INTDIR)\SpreadSheetInterface.class"
|
||||
|
||||
# ADD BASE JAVA /g
|
||||
# ADD JAVA /g
|
||||
|
||||
!ENDIF
|
||||
|
||||
################################################################################
|
||||
# Begin Target
|
||||
|
||||
# Name "spread - Java Virtual Machine Release"
|
||||
# Name "spread - Java Virtual Machine Debug"
|
||||
|
||||
!IF "$(CFG)" == "spread - Java Virtual Machine Release"
|
||||
|
||||
!ELSEIF "$(CFG)" == "spread - Java Virtual Machine Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
################################################################################
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\spread.html
|
||||
|
||||
!IF "$(CFG)" == "spread - Java Virtual Machine Release"
|
||||
|
||||
!ELSEIF "$(CFG)" == "spread - Java Virtual Machine Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
################################################################################
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\SpreadSheetInterface.java
|
||||
|
||||
!IF "$(CFG)" == "spread - Java Virtual Machine Release"
|
||||
|
||||
|
||||
"$(INTDIR)\Key.class" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
"$(INTDIR)\SpreadSheetInput.class" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
"$(INTDIR)\InputField.class" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
"$(INTDIR)\Node.class" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
"$(INTDIR)\Cell.class" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
"$(INTDIR)\SpreadSheet.class" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
"$(INTDIR)\SpreadSheetInterface.class" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "spread - Java Virtual Machine Debug"
|
||||
|
||||
|
||||
"$(INTDIR)\Key.class" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
"$(INTDIR)\SpreadSheetInput.class" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
"$(INTDIR)\InputField.class" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
"$(INTDIR)\Node.class" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
"$(INTDIR)\Cell.class" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
"$(INTDIR)\SpreadSheet.class" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
"$(INTDIR)\SpreadSheetInterface.class" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
################################################################################
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\PurePassThru.java
|
||||
|
||||
!IF "$(CFG)" == "spread - Java Virtual Machine Release"
|
||||
|
||||
|
||||
"$(INTDIR)\PurePassThru.class" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "spread - Java Virtual Machine Debug"
|
||||
|
||||
|
||||
"$(INTDIR)\PurePassThru.class" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
################################################################################
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\PureCashflow.java
|
||||
|
||||
!IF "$(CFG)" == "spread - Java Virtual Machine Release"
|
||||
|
||||
|
||||
"$(INTDIR)\PureCashflow.class" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "spread - Java Virtual Machine Debug"
|
||||
|
||||
|
||||
"$(INTDIR)\PureCashflow.class" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
################################################################################
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\money.java
|
||||
|
||||
!IF "$(CFG)" == "spread - Java Virtual Machine Release"
|
||||
|
||||
|
||||
"$(INTDIR)\Money.class" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "spread - Java Virtual Machine Debug"
|
||||
|
||||
|
||||
"$(INTDIR)\Money.class" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
################################################################################
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Prepayment.java
|
||||
|
||||
!IF "$(CFG)" == "spread - Java Virtual Machine Release"
|
||||
|
||||
|
||||
"$(INTDIR)\Prepayment.class" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "spread - Java Virtual Machine Debug"
|
||||
|
||||
|
||||
"$(INTDIR)\Prepayment.class" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
################################################################################
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Cashflow.java
|
||||
|
||||
!IF "$(CFG)" == "spread - Java Virtual Machine Release"
|
||||
|
||||
|
||||
"$(INTDIR)\Proto.class" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "spread - Java Virtual Machine Debug"
|
||||
|
||||
|
||||
"$(INTDIR)\Cashflow.class" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
################################################################################
|
||||
BIN
java/SPREAD/SPREAD.MDP
Normal file
BIN
java/SPREAD/SPREAD.MDP
Normal file
Binary file not shown.
BIN
java/SPREAD/SPREAD~1.CLA
Normal file
BIN
java/SPREAD/SPREAD~1.CLA
Normal file
Binary file not shown.
21
java/SPREAD/SPREAD~1.HTM
Normal file
21
java/SPREAD/SPREAD~1.HTM
Normal file
@@ -0,0 +1,21 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Paydown Calculator</title>
|
||||
</head>
|
||||
<body>
|
||||
<center>
|
||||
<font COLOR="#000080" size=+1>Diversified Software Solutions.</font>
|
||||
</center>
|
||||
<hr>
|
||||
<font COLOR="#000080" size=+1>Try the Paydown Calculator JAVA applet.</font>
|
||||
<font COLOR="#000080" size=0>
|
||||
<br>Inquiries, comments are welcome. We also provide customization services to meet your special needs. Please send email to
|
||||
</font>
|
||||
<A HREF="mailto:europa@li.net">europa@li.net</A>
|
||||
<hr>
|
||||
<applet code=Cashflow.class id=SpreadSheet width=640 height=520>
|
||||
</applet>
|
||||
<pr>
|
||||
<hr>
|
||||
</body>
|
||||
</html>
|
||||
930
java/SPREAD/SPREAD~1.SAF
Normal file
930
java/SPREAD/SPREAD~1.SAF
Normal file
@@ -0,0 +1,930 @@
|
||||
/*
|
||||
* @(#)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 SpreadSheet extends Applet
|
||||
{
|
||||
private final int mLeftArrow=1006;
|
||||
private final int mRightArrow=1007;
|
||||
private final int mUpArrow=1004;
|
||||
private final int mDownArrow=1005;
|
||||
private String mStrTitle;
|
||||
private Font mTitleFont;
|
||||
private Color mCellColor;
|
||||
private Color mInputColor;
|
||||
|
||||
private int mCellWidth=100;
|
||||
private int mCellHeight=15;
|
||||
|
||||
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;
|
||||
|
||||
public synchronized void init()
|
||||
{
|
||||
String strParam;
|
||||
|
||||
mCellColor=Color.white;
|
||||
mInputColor=new Color(100, 100, 225);
|
||||
mTitleFont=new Font("Courier", Font.BOLD, 12);
|
||||
mStrTitle=getParameter("title");
|
||||
if(null==mStrTitle)mStrTitle="SpreadSheet";
|
||||
strParam=getParameter("rows");
|
||||
if(null==strParam)mRows=9;
|
||||
else mRows=Integer.parseInt(strParam);
|
||||
strParam=getParameter("columns");
|
||||
if(null==strParam)mColumns=5;
|
||||
else mColumns=Integer.parseInt(strParam);
|
||||
mCells=new Cell[mRows][mColumns];
|
||||
char l[]=new char[1];
|
||||
for(int i=0; i < mRows; i++)
|
||||
{
|
||||
for (int j=0; j < mColumns; j++)
|
||||
{
|
||||
mCells[i][j]=new Cell(this,Color.lightGray,Color.black,mCellColor,mCellWidth-2,mCellHeight-2);
|
||||
l[0]=(char)((int)'a'+j);
|
||||
strParam=getParameter(""+new String(l)+(i+1));
|
||||
if(null!=strParam)mCells[i][j].setUnparsedValue(strParam);
|
||||
}
|
||||
}
|
||||
Dimension workArea=size();
|
||||
mInputArea=new SpreadSheetInput(null, this,workArea.width-2,mCellHeight-1,mInputColor,Color.white);
|
||||
resize(mColumns*mCellWidth+mRowLabelWidth,((mRows+1)*mCellHeight)+mCellHeight+mTitleHeight);
|
||||
}
|
||||
public void setCurrentValue(float val)
|
||||
{
|
||||
if(-1==mSelectedRow||-1==mSelectedColumn)return;
|
||||
mCells[mSelectedRow][mSelectedColumn].setValue(val);
|
||||
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()
|
||||
{
|
||||
for(int i=0;i<mRows;i++)for(int j=0;j<mColumns;j++)if(mCells[i][j].type()==Cell.URL)mCells[i][j].cellThread().stop();
|
||||
}
|
||||
public void setCurrentValue(int type,String val)
|
||||
{
|
||||
if(-1==mSelectedRow||-1==mSelectedColumn)return;
|
||||
mCells[mSelectedRow][mSelectedColumn].setValue(type,val);
|
||||
repaint();
|
||||
}
|
||||
public void update(Graphics graphics)
|
||||
{
|
||||
if(!mFullUpdate)
|
||||
{
|
||||
int cx;
|
||||
int cy;
|
||||
|
||||
graphics.setFont(mTitleFont);
|
||||
for(int row=0;row<mRows;row++)
|
||||
{
|
||||
for(int col=0;col<mColumns;col++)
|
||||
{
|
||||
if(mCells[row][col].needRedisplay())
|
||||
{
|
||||
cx=(col*mCellWidth)+2+mRowLabelWidth;
|
||||
cy=((row+1)*mCellHeight)+2+mTitleHeight;
|
||||
mCells[row][col].paint(graphics,cx,cy);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
paint(graphics);
|
||||
mFullUpdate = false;
|
||||
}
|
||||
}
|
||||
public synchronized void paint(Graphics graphics)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
int cx;
|
||||
int cy;
|
||||
char strLabel[]=new char[1];
|
||||
|
||||
Dimension clientRect=size();
|
||||
graphics.setFont(mTitleFont);
|
||||
graphics.drawString(mStrTitle,(clientRect.width-graphics.getFontMetrics().stringWidth(mStrTitle))/2,12);
|
||||
graphics.setColor(mInputColor);
|
||||
graphics.fillRect(0,mCellHeight,clientRect.width,mCellHeight);
|
||||
graphics.setFont(mTitleFont);
|
||||
for(i=0;i<mRows+1;i++)
|
||||
{
|
||||
cy=(i+2)*mCellHeight;
|
||||
graphics.setColor(getBackground());
|
||||
graphics.draw3DRect(0,cy,clientRect.width,2,true);
|
||||
if(i<mRows)
|
||||
{
|
||||
graphics.setColor(Color.red);
|
||||
graphics.drawString(""+(i+1),2,cy+12);
|
||||
}
|
||||
}
|
||||
graphics.setColor(Color.red);
|
||||
for(i=0;i<mColumns;i++)
|
||||
{
|
||||
cx=i*mCellWidth;
|
||||
graphics.setColor(getBackground());
|
||||
graphics.draw3DRect(cx+mRowLabelWidth,2*mCellHeight,1,clientRect.height,true);
|
||||
// if(i<mColumns)
|
||||
// {
|
||||
// graphics.setColor(Color.red);
|
||||
// strLabel[0]=(char)((int)'A'+i);
|
||||
// l[0]=(char)((int)'A'+i);
|
||||
// graphics.drawString(new String(strLabel),cx+mRowLabelWidth+(mCellWidth/2),clientRect.height-3);
|
||||
// }
|
||||
}
|
||||
|
||||
for(i=0;i<mRows;i++)
|
||||
{
|
||||
for(j=0;j<mColumns;j++)
|
||||
{
|
||||
cx=(j*mCellWidth)+2+mRowLabelWidth;
|
||||
cy=((i+1)*mCellHeight)+2+mTitleHeight;
|
||||
if(mCells[i][j]!=null)mCells[i][j].paint(graphics,cx,cy);
|
||||
}
|
||||
}
|
||||
graphics.setColor(getBackground());
|
||||
graphics.draw3DRect(0,mTitleHeight,clientRect.width,clientRect.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][col]!=null&&mCells[row][col].type()==Cell.FORMULA)
|
||||
{
|
||||
mCells[row][col].setRawValue(evaluateFormula(mCells[row][col].parseRoot()));
|
||||
mCells[row][col].needRedisplay(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
Cell cell;
|
||||
if(y<(mTitleHeight+mCellHeight))
|
||||
{
|
||||
mSelectedRow=-1;
|
||||
if(y<=mTitleHeight)deselect(true);
|
||||
return true;
|
||||
}
|
||||
if(x<mRowLabelWidth)
|
||||
{
|
||||
mSelectedRow=-1;
|
||||
deselect(true);
|
||||
return true;
|
||||
}
|
||||
mSelectedRow=((y-mCellHeight-mTitleHeight)/mCellHeight);
|
||||
mSelectedColumn=(x-mRowLabelWidth)/mCellWidth;
|
||||
if(mSelectedRow>mRows||mSelectedColumn>=mColumns)
|
||||
{
|
||||
mSelectedRow = -1;
|
||||
deselect(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mSelectedRow>=mRows)
|
||||
{
|
||||
mSelectedRow = -1;
|
||||
deselect(true);
|
||||
return true;
|
||||
}
|
||||
select();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public boolean keyDown(Event evt, int key)
|
||||
{
|
||||
mFullUpdate=true;
|
||||
if(mLeftArrow==key||mRightArrow==key||mUpArrow==key||mDownArrow==key)navigate(key);
|
||||
else mInputArea.keyDown(key);
|
||||
return true;
|
||||
}
|
||||
private void navigate(int key)
|
||||
{
|
||||
switch(key)
|
||||
{
|
||||
case mLeftArrow :
|
||||
if(mSelectedColumn<=0)break;
|
||||
mSelectedColumn--;
|
||||
select();
|
||||
break;
|
||||
case mRightArrow :
|
||||
if(mSelectedColumn>=mColumns)break;
|
||||
mSelectedColumn++;
|
||||
select();
|
||||
break;
|
||||
case mUpArrow :
|
||||
if(mSelectedRow<=0)break;
|
||||
mSelectedRow--;
|
||||
select();
|
||||
break;
|
||||
case mDownArrow :
|
||||
if(mSelectedRow>=mRows)break;
|
||||
mSelectedRow++;
|
||||
select();
|
||||
break;
|
||||
}
|
||||
}
|
||||
private void select()
|
||||
{
|
||||
Cell 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();
|
||||
requestFocus();
|
||||
mFullUpdate=true;
|
||||
repaint();
|
||||
}
|
||||
private void deselect(boolean destroy)
|
||||
{
|
||||
if(null==mCurrent)return;
|
||||
mCurrent.deselect();
|
||||
if(destroy)mCurrent=null;
|
||||
}
|
||||
}
|
||||
|
||||
// ******
|
||||
|
||||
class ScrollManager
|
||||
{
|
||||
private int mFirstVisibleCell;
|
||||
|
||||
public ScrollManager()
|
||||
{
|
||||
mFirstVisibleCell=0;
|
||||
}
|
||||
public int firstVisibleCell()
|
||||
{
|
||||
return mFirstVisibleCell;
|
||||
}
|
||||
public void firstVisibleCell(int firstVisibleCell)
|
||||
{
|
||||
mFirstVisibleCell=firstVisibleCell;
|
||||
}
|
||||
}
|
||||
|
||||
//******************************************************************************************************
|
||||
// ***************************************** CELLTHREAD ***********************************************
|
||||
//******************************************************************************************************
|
||||
class CellThread extends Thread
|
||||
{
|
||||
private Cell mTarget;
|
||||
private InputStream mDataStream=null;
|
||||
private StreamTokenizer mTokenStream;
|
||||
|
||||
public CellThread(Cell cell)
|
||||
{
|
||||
super("CellThread");
|
||||
mTarget=cell;
|
||||
}
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
mDataStream = new URL(mTarget.spreadSheet().getDocumentBase(),mTarget.getValueString()).openStream();
|
||||
mTokenStream = new StreamTokenizer(mDataStream);
|
||||
mTokenStream.eolIsSignificant(false);
|
||||
while(true)
|
||||
{
|
||||
switch(mTokenStream.nextToken())
|
||||
{
|
||||
case mTokenStream.TT_EOF:
|
||||
mDataStream.close();
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
case mTokenStream.TT_NUMBER:
|
||||
mTarget.setTransientValue((float)mTokenStream.nval);
|
||||
if(!mTarget.spreadSheet().stopped()&&!mTarget.paused())mTarget.spreadSheet().repaint();
|
||||
break;
|
||||
}
|
||||
try {Thread.sleep(2000);}
|
||||
catch(InterruptedException exception){break;}
|
||||
}
|
||||
}
|
||||
catch (IOException exception){return;}
|
||||
}
|
||||
}
|
||||
//******************************************************************************************************
|
||||
// ******************************************** 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 CellThread mCellThread;
|
||||
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;
|
||||
if(mType == Cell.URL)
|
||||
{
|
||||
mCellThread.stop();
|
||||
mCellThread=null;
|
||||
}
|
||||
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;
|
||||
mCellThread = new CellThread(this);
|
||||
mCellThread.start();
|
||||
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.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-2,mHeight-2);
|
||||
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 CellThread cellThread()
|
||||
{
|
||||
return mCellThread;
|
||||
}
|
||||
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 8: // delete
|
||||
--mChars;
|
||||
if(mChars<0)mChars=0;
|
||||
mBuffer[mChars] = 0;
|
||||
mStringValue = new String(new String(mBuffer));
|
||||
break;
|
||||
case 10: // 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
|
||||
{
|
||||
public SpreadSheetInput(String initValue,SpreadSheet app,int width,int height,Color bgColor,Color fgColor)
|
||||
{
|
||||
super(initValue,app,width,height,bgColor,fgColor);
|
||||
}
|
||||
public void selected()
|
||||
{
|
||||
float f;
|
||||
|
||||
switch(getValue().charAt(0))
|
||||
{
|
||||
case 'v':
|
||||
try{f=Float.valueOf(getValue().substring(1)).floatValue();((SpreadSheet)applet()).setCurrentValue(f);}
|
||||
catch(NumberFormatException exception){;}
|
||||
break;
|
||||
case 'l':
|
||||
((SpreadSheet)applet()).setCurrentValue(Cell.LABEL,getValue().substring(1));
|
||||
break;
|
||||
case 'u':
|
||||
((SpreadSheet)applet()).setCurrentValue(Cell.URL,getValue().substring(1));
|
||||
break;
|
||||
case 'f':
|
||||
((SpreadSheet)applet()).setCurrentValue(Cell.FORMULA,getValue().substring(1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
java/SPREAD/SPREAD~2.CLA
Normal file
BIN
java/SPREAD/SPREAD~2.CLA
Normal file
Binary file not shown.
BIN
java/SPREAD/SPREAD~3.CLA
Normal file
BIN
java/SPREAD/SPREAD~3.CLA
Normal file
Binary file not shown.
1007
java/SPREAD/SPREAD~7.JAV
Normal file
1007
java/SPREAD/SPREAD~7.JAV
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user