Excel's Table Editor Implementation
Sources
Cell.java
import java.text.ParseException;
/*
Class representing Cell of the grid. Especially cell with double type
*/
public class Cell {
/*
Reference to parent grid object
*/
protected Grid grid;
/*
The input value of the cell
*/
private String value = "";
/*
Cell constructor, using grid instance
*/
public Cell(Grid grid) {
this.grid = grid;
}
/*
Returns the double value of the current cell, if it is not empty
In case it is empty, 0.0 is returned
*/
public double getValue() {
if (value.isEmpty())
return 0.0;
return Double.parseDouble(value);
}
/*
Method for setting input value to the current cell
*/
public void setValue(String value) throws ParseException {
this.value = value;
}
/*
Getter method for the input value
*/
public String getInputString() {
return value;
}
/*
Override toString method for cell object.
For Cell class, it returns "", if the cell is empty, and the String representation of the double value if it is not empty
*/
@Override
public String toString() {
if (value.isEmpty()) {
return "";
}
return "" + getValue();
}
/*
Factory static method for creating a cell of the appropriate type, according to the input string
*/
public static Cell parseCell(Grid grid, String value) throws ParseException {
String[] tokens = value.split(" ");
// Looking at the first token of the input string
// If the first token is "("than it is a formula
if (tokens[0].equals("(")) {
FormulaCellformulaCell = new FormulaCell(grid);
formulaCell.setValue(value);
return formulated;
}
// If the first token is ", then it is text
if (tokens[0].equals("\"")) {
TextCelltextCell = new TextCell(grid);
textCell.setValue(value);
return textCell;
}
// If the first token contains "/" than it is the date
if (tokens[0].contains("/")) {
DateCelldateCell = new DateCell(grid);
dateCell.setValue(value);
return dateCell;
}
// Otherwise it is usual double-value set
Cell cell = new Cell(grid);
cell.setValue(value);
return cell;
}
}
DateCell.java
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
Class inherited from cell object. Represents Date-type object
*/
public class DateCellextends Cell {
// Default date format patterm
public static final DateFormatdateFormat = new SimpleDateFormat("mm/dd/yyyy");
// Date of the cell
private Date date;
/*
Default constructor with grid argument
*/
public DateCell(Grid grid) {
super(grid);
}
/*
Override setValue method
*/
@Override
public void setValue(String value) throws ParseException {
super.setValue(value);
// To get value, we just parse value with a given format pattern
date = dateFormat.parse(value);
}
// Overridden toString method. If not string returns text
@Override
public String toString() {
if (getInputString().isEmpty()) {
return "";
}
return "" + dateFormat.format(date);
}
// Getter method for date field
public Date getDate() {
return date;
}
}
FormulaCell.java
import java.text.ParseException;
import java.util.LinkedList;
import java.util.List;
/*
Class inherited from cell object. Represents Formula-type object
*/
public class FormulaCellextends Cell {
// Boolean value, showing if the current value is "Not-a-Number"
private booleanisNan = false;
// List of operations (+,-*,/) in formula
private LinkedList operations = new LinkedList<>();
// List of expressions (literal, cells, sum, avg) in the formula
private LinkedListexps = new LinkedList<>();
/*
Default constructor with grid argument
*/
public FormulaCell(Grid grid) {
super(grid);
}
/*
Overridden getValue method. Tries to calculate the formula. Sets Nan to true, if it is not possible
*/
@Override
public double getValue() {
isNan = false;
// Copying operations and exps lists
LinkedListopCopy = new LinkedList<>();
for (String s: operations) {
opCopy.addLast(s);
}
LinkedListexpCopy = new LinkedList<>();
for (Exp e: exps) {
expCopy.addLast(e);
}
// Perform calculations until expCopy list contains only one object
while (expCopy.size() >1) {
// Extracting top expCopy expression
Exp exp1 = expCopy.pop();
if (exp1.isNan()) {
// If it is Nan returning 0.0 and setting Nan to true
isNan = true;
return 0.0;
}
// Extracting next top expCopy expression
Exp exp2 = expCopy.pop();
if (exp2.isNan()) {
// If it is Nan returning 0.0 and setting Nan to true
isNan = true;
return 0.0;
}
// Getting values of extracted expressions
double val1 = exp1.getValue(grid);
double val2 = exp2.getValue(grid);
// Making calculations with the appropriate operation
double newVal = 0.0;
// This operation is obtained from the top of opCopy list
String op = opCopy.pop();
if ("+".equals(op)) {
newVal = val1 + val2;
}
else if ("-".equals(op)) {
newVal = val1 - val2;
}
else if ("*".equals(op)) {
newVal = val1 * val2;
}
else if ("/".equals(op)) {
newVal = val1 / val2;
}
// PUshing result of the calculation on the top of expCopy list, as a literal expression
expCopy.push(new LiteralExp(newVal));
}
/*
Static class for representing Range expression
*/
public static class RangeExp {
// Fields, representing border indices of range in spreadsheet array
private int topRow;
private int bottom row;
private int leftColumn;
private int rightColumn;
/*
Constructor for creating an instance of RangeExp from to Cell expressions
*/
public RangeExp(FormulaCell.CellExp cell1, FormulaCell.CellExp cell2) {
this.topRow = Math.min(cell1.getRow(), cell2.getRow());
this.bottomRow = Math.max(cell1.getRow(), cell2.getRow());
this.leftColumn = Math.min(cell1.getColumn(), cell2.getColumn());
this.rightColumn = Math.max(cell1.getColumn(), cell2.getColumn());
}
}
}