Está en la página 1de 27

UNIVERSIDAD PERUANA LOS ANDES

FACULTAD DE INGENIERA DE SISTEMAS Y COMPUTACIN


PROGRAMA UTILIZANDO EL MTODO 6D
HOJA ELECTRNICA
TRABAJO PRESENTADO POR:
CURSO:
DOCENTE:
SEMESTRE:
HUANCAYO - PER
LOZANO MELCHOR EDUARDO
SANCHEZ GUILLEN JUAN JOS
PROYECTO DE PROGRAMACIN
Dr. ABRAHAM GAMARRA MORENO
VII


PROYECTO UTILIZANDO EL MTODO 6D
HOJA ELECTRNICA
Etapa 01 - Descripcin del problema.
Desarrollar un proyecto que nos permita realizar clculos matemticos simples, el presente
proyecto simula una hoja de clculo el cual tendr celdas para poder hacer las operaciones
bsicas como: suma, resta, multiplicacin, divisin, potenciacin, mostrar los resultados en a
celda y guardar el archivo, a la vez se podr insertar filas y columnas de la misma forma que
se puede eliminar las mismas.
Etapa 02 - Definicin de la solucin.
Resultado deseado:
Mostrar el resultado de operaciones bsicas como suma, resta, divisin, multiplicacin,
potenciacin.
Nos permitir incrementar as como eliminar filas y columnas.
Datos necesarios: Ingresar los datos como nmeros reales para poder realizar la operacin
Procesamiento:
Los nmeros ingresados en una celda se operaran y el resultado se mostrar en la misma celda

Etapa 03 - Diseo de la lgica.
Para solucionar el problema se desarrollarn las especificaciones del proyecto en UML y el
algoritmo en pseudocdigo.
1. Nombre del Proyecto: hojaelectronica
2. Definicin de Paquetes y desarrollo de Diagrama de Paquetes.

3. Definicin de las Clases.












4. Diseo de algoritmo para el mtodo principal
HOJAELECTRNICA .dat

package hojaelectronica.dat;
import java.io.File;
import javax.swing.filechooser.FileFilter;
/**
* Esta clase representa el filtro para la seleccion de archivos
* en los dialogos de <b>abrir</b> y de <b>guardar</b>.<p>
* Extiende de <i>FileFilter</i> e implementalos metodos necesarios
* para hacer un filtrado unico de un tipo de archivo, en este caso
* el tipo de archivo es seleccionado con la extension <i>.cam</i>.
*/
public class FiltroArchivoextends FileFilter {
public boolean accept(File f) {
if(f.isDirectory())
returntrue;
if (f.getName().endsWith(".cam"))
returntrue;
returnfalse;
}
public String getDescription() {
return"\"*.cam\" Archivode Hojade Calculo - Proyectode Programacion";
}
}
FILTRO ARCHIVO

MODELOCOLUMNASTABLA
package hojaelectronica.dat;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableColumn;
/**
* Esta clase determina el modelo de las columnas enla tabla, son
* de untipoespecial ya que deseamos determinar un tamao minimo
* para las columnas, ademas de tener la capacidad de darle un aspecto
* mas personalizadoa las columnas en una tabla.
*/
public class ModeloColumnasTabla extends DefaultTableColumnModel {
/**
* Esta variable ayuda a saltar la primera columna de la tabla
* que como veremos es la columna de la autonumeracion.
*/
private boolean primera = true;
public voidaddColumn(TableColumn tc) {
if (primera)
primera= false;
else {
tc.setMinWidth(150);
super.addColumn(tc);
}
}
}

MODELOFILASTABLA
package hojaelectronica.dat;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableColumn;
/**
* Esta clase determina las propiedades de las filas de la primera
* columna, que es la columna de autonumeracion.
*/
public class ModeloFilasTabla extends DefaultTableColumnModel {
/**
* Representa si es la primera columna de la tabla.
*/
private boolean first = true;
public voidaddColumn(TableColumn tc) {
// Solo nos interesa la primera, el resto no importa
if(first) {
tc.setMaxWidth(25);
super.addColumn(tc);
first = false;
}
}
}

MODELO TABLA

package hojaelectronica.dat;
import java.util.Vector;
import javax.swing.table.AbstractTableModel;
import hojaelectronica.gui.HojaCalculo;
import hojaelectronica.log.DemultiplexorExpresion;
import hojaelectronica.log.DemutiplexorFormula;
/**
* Esta clase representa el modelo de la tabla, con lo cual se convierte en el patrn a seguir de
la tabla, si se quisiera modificar alguna caracterstica de la tabla, se debe hacer desde aqu.
*/
public class ModeloTabla extends AbstractTableModel {
/**
* Representa los nombres de las columnas de la tabla
*/
private Vector encabezados = new Vector();
/**
* Representa los datos de la tabla
*/
private String datos[][] = new
String[HojaCalculo.CANTIDAD_FILAS][HojaCalculo.CANTIDAD_COLUMNAS+1];
/**
* Representa la clase que resuelve la expresin
*/
private DemultiplexorExpresion demultiplexorExpresion;
/**
* Representa la clase que resuelve la formula
*/
private DemutiplexorFormula demultiplexorFormula;
/**
* Constructor de la clase, les da nombres a las columnas de la tabla.<p>
* <b>La etiquetacin de las columnas con letras, solamente
* son vlidas hasta el valor de 26</b>.
*/
public ModeloTabla() {
char letra = 'A';
encabezados.add(Character.toString('#'));
for(int i=0; i < HojaCalculo.CANTIDAD_COLUMNAS; i++) {
encabezados.add(Character.toString(letra));
letra++;
}
for(int i=0; i < HojaCalculo.CANTIDAD_FILAS; i++) {
datos[i][0] = Integer.toString(i);
}
fireTableStructureChanged();
}

/**
* Mtodo que retorna la cantidad de filas.
*/
public int getRowCount() {
return datos.length;
}

/**
* Mtodo que retorna la cantidad de columnas.
*/
public int getColumnCount() {
return encabezados.size();
}

/**
* Metodo que retorna el nombre de las columnas.
*/
public String getColumnName(int column) {
return (String) encabezados.elementAt(column);
}

/**
* Mtodo que retorna el objeto situado en los parmetros.
*/
public Object getValueAt(int rowIndex, int columnIndex) {
if (columnIndex == 0)
return Integer.toString(rowIndex+1);
else
return datos[rowIndex][columnIndex];
}

/**
* Mtodo que determina si una celda es editable o no.
*/
public boolean isCellEditable(int rowIndex, int columnIndex) {
// No queremos que sean editables las celdas de autonumeracion
if (columnIndex == 0)
return false;
else
return true;
}

/**
* Mtodo que actualiza la informacin de una celda. <p>
* Adems determina el tipo de dato que fue introducido y hace la operacin
correspondiente al tipo de dato.
*/
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
// Verificamos que no sea nulo ni que sea de tamao cero
if(aValue != null && ((String) aValue).length() != 0) {
if(((String) aValue).startsWith("=")) {
// Formula
demultiplexorFormula = new DemutiplexorFormula(this,
(String) aValue);
datos[rowIndex][columnIndex] =
String.valueOf(demultiplexorFormula.getValor());
}
else if((Character.isDigit(((String) aValue).charAt(0)))) {
// Operacin
demultiplexorExpresion = new DemultiplexorExpresion((String)
aValue);
datos[rowIndex][columnIndex] =
String.valueOf(demultiplexorExpresion.getValor());
}
else if((Character.isLetter(((String) aValue).charAt(0)))) {
// Texto
datos[rowIndex][columnIndex] = (String) aValue;
}
}
else // Celda Vaca
datos[rowIndex][columnIndex] = null;

fireTableDataChanged();
}

/**
* Mtodo que cambia todos los datos de la tabla por los
* recibidos como parmetro, este mtodo fue creado con el fin
* de hacer compatible la tabla con <i>Abrir</i>.
* @param str String[][] con todos los nuevos datos
*/
public void setAllData(String[][] str) {
for(int i=0; i < HojaCalculo.CANTIDAD_FILAS; i++)
for(int j=0; j < HojaCalculo.CANTIDAD_COLUMNAS+1; j++)
datos[i][j] = str[i][j];
fireTableDataChanged();
}

/**
* Mtodo que retorna todos los datos de la tabla, este
* mtodo fue creado con el fin de hacer compatible la
* tabla con <i>Guardar</i>.
* @return String[][] con todos los datos de la tabla
*/
public String[][] getAllData() {
return datos;
}
}
SELECCIONADORDEARCHIVOS

package hojaelectronica.dat;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import hojaelectronica.gui.HojaCalculo;
import hojaelectronica.log.builder.PanelHojaCalculo;
/**
* Esta clase provee los mtodos necesarios para <i>abrir</i> y
* <i>guardar</i> en la aplicacin.
*/
public class SeleccionadorArchivos {
/**
* Representa el archivo en el cual se trabaja actualmente.
*/
public File archivoActual;
/**
* Este mtodo carga en la tabla el archivo que recibe por parmetro.
* @param archivo Archivo a abrir
*/
public void abrirArchivo(File archivo) {
try {
ObjectInputStream ois = new ObjectInputStream(new
FileInputStream(archivo));
((PanelHojaCalculo)
HojaCalculo.getInstancia().constructor).setAllDataToModel((String[][]) ois.readObject());
ois.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
archivoActual = archivo;
}

/**
* Este mtodo almacena los datos de la tabla en el archivo pasado por parmetro.
* @param archivo Archivo a guardar
*/
public void guardarArchivo(File archivo) {
try {
ObjectOutputStream oos = new ObjectOutputStream(new
FileOutputStream(archivo));
String[][] datos = ((PanelHojaCalculo)
HojaCalculo.getInstancia().constructor).getAllDataFromModel();
oos.writeObject(datos);
oos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
archivoActual = archivo;
}

/**
* Mtodo para guardar cambios en el archivo actual.
*/
public void guardar() {
try {
ObjectOutputStream oos = new ObjectOutputStream(new
FileOutputStream(archivoActual));
String[][] datos = ((PanelHojaCalculo)
HojaCalculo.getInstancia().constructor).getAllDataFromModel();
oos.writeObject(datos);
oos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
HOJAELECTRNICA .gui

DILOGOPARAELIMINAR

package hojaelectronica.dat;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import hojaelectronica.gui.HojaCalculo;
import hojaelectronica.log.builder.PanelHojaCalculo;
/**
* Esta clase provee los mtodos necesarios para <i>abrir</i> y
* <i>guardar</i> en la aplicacin.
*/
public class SeleccionadorArchivos {
/**
* Representa el archivo en el cual se trabaja actualmente.
*/
public File archivoActual;
/**
* Este mtodo carga en la tabla el archivo que recibe por parmetro.
* @param archivo Archivo a abrir
*/
public void abrirArchivo(File archivo) {
try {
ObjectInputStream ois = new ObjectInputStream(new
FileInputStream(archivo));
((PanelHojaCalculo)
HojaCalculo.getInstancia().constructor).setAllDataToModel((String[][]) ois.readObject());
ois.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
archivoActual = archivo;
}
/**
* Este mtodo almacena los datos de la tabla en el archivo pasado por parmetro.
* @param archivo Archivo a guardar
*/
public void guardarArchivo(File archivo) {
try {
ObjectOutputStream oos = new ObjectOutputStream(new
FileOutputStream(archivo));
String[][] datos = ((PanelHojaCalculo)
HojaCalculo.getInstancia().constructor).getAllDataFromModel();
oos.writeObject(datos);
oos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
archivoActual = archivo;
}

/**
* Mtodo para guardar cambios en el archivo actual.
*/
public void guardar() {
try {
ObjectOutputStream oos = new ObjectOutputStream(new
FileOutputStream(archivoActual));
String[][] datos = ((PanelHojaCalculo)
HojaCalculo.getInstancia().constructor).getAllDataFromModel();
oos.writeObject(datos);
oos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

DILOGOPARAINSERTAR

package hojaelectronica.gui;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import hojaelectronica.log.builder.PanelHojaCalculo;

/**
* Esta clase representa el dialogo de insertar filas o columnas en la tabla.
* Extiende de <i>JDialog</i> e implementa <i>KeyListener</i>.
*/
public class DialogoInsertar extends JDialog implements KeyListener {
/**
* Representa la cantidad de filas
*/
private JTextField cantidadFilas = new JTextField(5);
/**
* Representa la cantidad de columnas
*/
private JTextField cantidadColumnas = new JTextField(5);
/**
* Representa el botn de aceptar
*/
private JButton aceptarBtn = new JButton("Aceptar");
/**
* Representa el botn de cancelar
*/
private JButton cancelarBtn = new JButton("Cancelar");
/**
* Representa la seleccin de filas
*/
private JRadioButton filasRadioBtn = new JRadioButton("Filas", true);
/**
* Representa la seleccin de columnas
*/
private JRadioButton columnasRadioBtn = new JRadioButton("Columnas");
/**
* Representa el grupo de selecciones
*/
private ButtonGroup buttonGroup = new ButtonGroup();
/**
* Constructor de la clase, genera el dialogo donde se puede seleccionar si se quieren
insertar filas o columnas y cuantas.<p>
* En cada caso, decide que accin tomar para cada opcin.
*
*/
public DialogoInsertar() {
cantidadFilas.addKeyListener(this);
cantidadColumnas.addKeyListener(this);
filasRadioBtn.addKeyListener(this);
columnasRadioBtn.addKeyListener(this);
buttonGroup.add(filasRadioBtn);
buttonGroup.add(columnasRadioBtn);

add(filasRadioBtn);
add(cantidadFilas);
add(columnasRadioBtn);
add(cantidadColumnas);

aceptarBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
if(filasRadioBtn.isSelected() &&
Integer.parseInt(cantidadFilas.getText()) > 0) {

((PanelHojaCalculo)HojaCalculo.getInstancia().constructor).insertarFilas(Integer.parseI
nt(cantidadFilas.getText()));
}
else if(columnasRadioBtn.isSelected() &&
Integer.parseInt(cantidadColumnas.getText()) > 0) {

((PanelHojaCalculo)HojaCalculo.getInstancia().constructor).insertarColumnas(Integer.p
arseInt(cantidadColumnas.getText()));
}
else
System.err.println("Debe ser un numero mayor
que cero");
} catch (NumberFormatException e1) {
System.err.println("Debe digitar un numero!!!");
}
dispose();
}
});
add(aceptarBtn);

cancelarBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
add(cancelarBtn);

setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setLayout(new GridLayout(3,2));
setSize(220,110);
setTitle("Insertar...");
setLocation(Toolkit.getDefaultToolkit().getScreenSize().width/2-125,
Toolkit.getDefaultToolkit().getScreenSize().height/2-125);
setResizable(false);
setModal(true);
setAlwaysOnTop(true);
setVisible(true);
}

/**
* Listener de teclado para el dialogo de peticin de datos.
*/
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER)
aceptarBtn.doClick();
if(e.getKeyCode() == KeyEvent.VK_ESCAPE)
cancelarBtn.doClick();
}

public void keyTyped(KeyEvent e) {
}

public void keyPressed(KeyEvent e) {
}
}

HOJADECLCULO

package hojaelectronica.log.builder;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JToolBar;

import hojaelectronica.gui.DialogoEliminar;
import hojaelectronica.gui.DialogoInsertar;

/**
* Esta clase construye una barra de herramientas para la aplicacin
*/

public class BarraHerramientas extends JToolBar implements ConstructorAbstracto {

/**
* Representa el botn de insertar filas o columnas
*/
private JButton insertarBoton = new JButton("Insertar");

/**
* Representa el botn de eliminar filas o columnas
*/
private JButton eliminarBoton = new JButton("Eliminar");

/**
* Constructor de la clase. Genera la barra de herramientas y le da utilidad a sus
botones.
*
*/
public BarraHerramientas() {
insertarBoton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
new DialogoInsertar();
}
});
insertarBoton.setToolTipText("Insertar Filas o Columnas");

eliminarBoton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
new DialogoEliminar();
}
});
eliminarBoton.setToolTipText("Eliminar la Seleccion Actual");

add(insertarBoton);
add(eliminarBoton);
}
}

Esta quiz es la clase ms importante de la aplicacin ya que es la que convierte la entrada en
la salida, funciona para funciones matemticas bsicas, como suma, resta, multiplicacin,
divisin, exponenciacin y precedencia de parntesis.
Para hacer dicha operacin lo fundamental de la clase es el uso de las pilas posfija y de
operadores.
El uso de dichas pilas garantiza la resolucin de la expresin matemtica lo ms ptimamente
posible adems de lo ms fcil para entender.
El mtodo que se sigue es el siguiente, se utiliza una pila de operadores en la cual se almacena
por precedencia de importancia cada operador que venga en la expresin a evaluar, y se utiliza
una pila posfija en la cual se resuelven las operaciones conforme lleguen a la pila, de tal forma
que se garantiza la precedencia de los operadores y la precisin en el clculo de la expresin.

package hojaelectronica.log;

import java.util.Stack;
import java.util.StringTokenizer;



public class DemultiplexorExpresion {
/**
* EOL representa el fin de lnea el cual se utiliza para determinar en qu parte
* termina la sentencia.
*/
private static final int EOL = 0;
/**
* Representa el operando de la expresin "911"
*/
private static final int VALOR = 1;

/**
* Representa el parntesis que abre "("
*/
private static final int ABRE = 2;

/**
* Representa el parntesis que cierra ")"
*/
private static final int CIERRA = 3;

/**
* Representa el operador exponencial "^"
*/
private static final int EXP = 4;

/**
* Representa el operador multiplicador "*"
*/
private static final int MULT = 5;

/**
* Representa el operador de division "/"
*/
private static final int DIV = 6;

/**
* Representa el operador de suma "+"
*/
private static final int SUMA = 7;

/**
* Representa el operador de resta "-"
*/
private static final int RESTA = 8;

/**
* Representa la tabla de precedencia de los operadores, aqu es donde se asigna que
precedencia
* tiene cada operador en la pila.
*/
private static PrecedenciaOperadores[] tablaPrecedencia = new PrecedenciaOperadores[] {
new PrecedenciaOperadores(0, -1), // EOL
new PrecedenciaOperadores(0, 0), // VALOR
new PrecedenciaOperadores(100, 0), // ABRE
new PrecedenciaOperadores(0, 99), // CIERRA
new PrecedenciaOperadores(6, 5), // EXP
new PrecedenciaOperadores(3, 4), // MULT
new PrecedenciaOperadores(3, 4), // DIV
new PrecedenciaOperadores(1, 2), // SUMA
new PrecedenciaOperadores(1, 2) // RESTA
};

/**
* Representa la pila de operadores
*/
private Stack pilaOperadores;

/**
* Representa la pila posfija
*/
private Stack pilaPosfija;

/**
* Representa el Tokenizer de la expresin
*/
private StringTokenizer str;

/**
* Esta clase representa la precedencia de los operadores que est dada por
* un identificador de smbolo de entrada y otro de cima de la pila.
*/
private static class PrecedenciaOperadores {

/**
* Representa el smbolo de entrada
*/
public int simboloEntrada;

/**
* Representa la cima de la pila
*/
public int cimaPila;

/**
* Constructor de la clase, asigna los valores pasados por parmetro
* @param simboloEntrada Smbolo de Entrada
* @param cimaPila Smbolo de Cima de la Pila
*/
public PrecedenciaOperadores(int simboloEntrada, int cimaPila) {
this.simboloEntrada = simboloEntrada;
this.cimaPila = cimaPila;
}
}

/**
* Esta clase representa los Token de la expresin, de tal manera que convierte
* un token de la forma "+" a su valor numrico para que pueda ser evaluado
* por las pilas.
* @author Camilo Nova
*/
private static class Token {

/**
* Representa el tipo del token
*/
private int tipo = EOL;

/**
* Representa el valor del Token
*/
private double valor = 0;

/**
* Constructor de la clase.
*
*/
public Token() {
this(EOL);
}

/**
* Constructor de la clase.
* @param t Tipo del token
*/
public Token(int t) {
this(t, 0);
}

/**
* Constructor de la clase.
* @param t Tipo del Token
* @param v Valor del Token
*/
public Token(int t, double v) {
tipo = t;
valor = v;
}

/**
* Retorna el tipo del Token
* @return Tipo del Token
*/
public int getTipo() {
return tipo;
}

/**
* Retorna el valor del Token
* @return Valor del Token
*/
public double getValor() {
return valor;
}
}

/**
* Esta clase evala el String Tokenizer enviado por parmetro, y convierte a Tokens sus
operadores, con el fin de evaluar la expresin.
*/
private static class EvaluadorToken {

/**
* Representa el Conjunto de Tokens
*/
private StringTokenizer str;

/**
* Constructor de la clase, asigna el valor enviado por parmetro.
* @param is StringTokenizer con los tokens
*/
public EvaluadorToken(StringTokenizer is) {
str = is;
}

/**
* Encuentra el Token siguiente, salta los espacios, y lo retorna.
* Para el Token VALOR, Asigna el valor procesado a valorActual.
* Imprime error si el valor no se reconoce.
*/
public Token getToken() {
double valorActual;

if(!str.hasMoreTokens())
return new Token();

String s = str.nextToken();
if(s.equals(" ")) return getToken();
if(s.equals("^")) return new Token(EXP);
if(s.equals("/")) return new Token(DIV);
if(s.equals("*")) return new Token(MULT);
if(s.equals("(")) return new Token(ABRE);
if(s.equals(")")) return new Token(CIERRA);
if(s.equals("+")) return new Token(SUMA);
if(s.equals("-")) return new Token(RESTA);

try {
valorActual = Double.parseDouble(s);
}
catch(NumberFormatException e) {
System.err.println("Error en Numero!!!");
return new Token();
}

return new Token(VALOR, valorActual);
}
}

/**
* Constructor de la clase. Crea las pilas y convierte a tokens el parmetro recibido.
* @param s Cadena a evaluar
*/
public DemultiplexorExpresion(String s) {
pilaOperadores = new Stack();
pilaPosfija = new Stack();

str = new StringTokenizer(s, "+*-/^() ", true);

pilaOperadores.push(new Integer(EOL));
}

/**
* Mtodo que calcula el valor de la expresin, llamando a los mtodos de esta clase.
* @return Valor numrico de la expresin.
*/
public double getValor() {
EvaluadorToken tok = new EvaluadorToken(str);
Token ultimoToken;

do {
ultimoToken = tok.getToken();
procesarToken(ultimoToken);
} while(ultimoToken.getTipo() != EOL);

if(pilaPosfija.isEmpty()) {
System.err.println("Falta un Operador!");
return 0;
}

double resultado = posfijaTopAndPop();

if(!pilaPosfija.isEmpty())
System.err.println("Warning: Falta operador!");

return resultado;
}

/**
* Luego de que el Token sea ledo, se utiliza la precedencia
* de los operadores para procesarlo, si existen parntesis
* abiertos son detectados aqu.
*/
private void procesarToken(Token ultimoToken){
int topOp;
int lastType = ultimoToken.getTipo( );

switch(lastType) {
case VALOR:
pilaPosfija.push(new Double(ultimoToken.getValor()));
return;

case CIERRA:
while((topOp = operadoresTop()) != ABRE && topOp != EOL)
binaryOp(topOp);
if(topOp == ABRE)
pilaOperadores.pop();
else
System.err.println("Falta un ABRE");
break;

default: // Operador
while(tablaPrecedencia[lastType].simboloEntrada <= tablaPrecedencia[topOp =
operadoresTop()].cimaPila)
binaryOp(topOp);
if(lastType != EOL)
pilaOperadores.push(new Integer(lastType));
break;
}
}

/**
* Retorna el resultado de la pila posfija, si la pila esta
* vaca retorna cero e imprime error.
*/
private double getTop() {
if (pilaPosfija.isEmpty()) {
System.err.println("Falta un Operador");
return 0;
}
return posfijaTopAndPop();
}

/**
* Procesa un operador tomando dos elementos de la pila posfija, aplica el operador y
retorna el resultado a la pila.
*/
private void binaryOp(int topOp) {
double rhs = getTop();
double lhs = getTop();

if( topOp == ABRE ) {
System.err.println("Parentesis desbalanceado");
pilaOperadores.pop();
return;
}

if(topOp == EXP)
pilaPosfija.push(new Double(Math.pow(lhs, rhs)));
else if(topOp == SUMA)
pilaPosfija.push(new Double(lhs + rhs));
else if(topOp == RESTA)
pilaPosfija.push(new Double(lhs - rhs));
else if(topOp == MULT)
pilaPosfija.push(new Double(lhs * rhs));
else if(topOp == DIV)
if(rhs != 0 )
pilaPosfija.push(new Double(lhs / rhs));
else {
System.err.println("Division por cero");
pilaPosfija.push(new Double(lhs));
}
pilaOperadores.pop();
}

/**
* Retorna el elemento de la cima de la pila posfija
* @return Elemento de la cima
*/
private double posfijaTopAndPop() {
return ((Double)(pilaPosfija.pop())).doubleValue();
}

/**
* Retorna el elemento de la cima de la pila de operadores
* @return Elemento de la cima
*/
private int operadoresTop() {
return ((Integer)(pilaOperadores.peek())).intValue();
}
}













































Esta clase convierte el valor de una formula entrada a una expresin matemtica para que sea
evaluada por la clase.
La forma en la que se reconoce de que se trata de una frmula es porque comienza con el
smbolo "=", entonces esta clase convierte el valor de una celda al valor numrico para calcular
el valor de la expresin.

package hojaelectronica.log;

import java.util.StringTokenizer;

import javax.swing.table.AbstractTableModel;
public class DemutiplexorFormula {

/**
* Representa la cadena en donde se arma la expresion matematica
*/
private String cadena;

/**
* Representa la fila a la que hace referencia la entrada
*/
private String fila;

/**
* Representa la columna a la que hace referencia la entrada
*/
private String columna;

/**
* Representa el Tokenizer que usamos para separar la expresion en Tokens
*/
private StringTokenizer strToken;

/**
* Representa el dato de la celda a la cual hace referencia <i>fila</i> y <i>columna</i>.
*/
private String datoCelda;

/**
* Representa si el token representa una celda, si es una celda el valor es true
*/
private boolean isCelda = false;

/**
* Representa el Demultiplexor de la expresion matematica.
*/
private DemultiplexorExpresion demultiplexorExpresion;


/**
* Constructor de la clase, recibe como parametros la tabla en la cual
* buscar los valores y la cadena a convertir.<p>
* La responsabilidad de la clase es la de convertir una espresion de tipo
* "=A3*B5", al tipo "(valor de A3)*(valor de B5)" y enviarla a
<i>DemultiplexorExpresion</i>
* a que la resuelva.
* @param tabla Tabla de la cual recuperar los datos
* @param cad Cadena a convertir
*/
public DemutiplexorFormula(AbstractTableModel tabla, String cad) {
strToken = new StringTokenizer(cad, "=+*-/^() ", true);
cadena = new String();
fila = new String();
columna = new String();

while(strToken.hasMoreTokens()) {
String g = strToken.nextToken();
// Nos saltamos los siguientes tokens
if(!g.equals("=") && !g.equals(" ")) {
char a = 'A';
for(int i=0; i < 26; i++) {
if(g.startsWith(Character.toString(a))) {
isCelda = true;
StringTokenizer str = new StringTokenizer(g,
Character.toString(a), true);
if(str.countTokens() == 2) {
// Validamos que solamente existan 2
Tokens
columna = str.nextToken();
fila = str.nextToken();

try {
datoCelda = (String)
tabla.getValueAt(Integer.valueOf(fila).intValue()-1, validarColumna(columna));
} catch (NumberFormatException e) {
System.err.println("Celda no
valida");
return;
}

if(datoCelda == null) {
System.err.println("La Celda " +
columna + fila + " no contiene ningun valor");
return;
}
cadena += datoCelda;
}
else {
System.err.println("Celda no valida");
return;
}
}
a++;
}
if(!isCelda)
cadena += g;

// Volvemos a la condicion inicial
isCelda = false;
}
}
demultiplexorExpresion = new DemultiplexorExpresion(cadena);
}

/**
* Metodo que retorna el valor de la expresion, luego de ser
* calculado por <i>DemultiplexorExpresion</i>. Retorna cero
* si ocurre algun error en la evaluacion de la cadena.
* @return Valor numerico de la expresion
*/
public double getValor() {
// Si ocurre un error en la evaluacion de la expresion
if(demultiplexorExpresion == null)
return 0;
else
return demultiplexorExpresion.getValor();
}

/**
* Metodo que convierte el valor del parametro s a su equivalente
* en entero para la ubicacion en la tabla
* @param s Cadena con el nombre de la columna
* @return Entero que representa la posicion de la columna
*/
private int validarColumna(String s) {
char c = 'A';

for(int i=0; i < 26; i++) {
if(s.charAt(0) == c)
return i+1;
c++;
}
return 0;
}
}