Added graphical interface and cleaned up the code

This commit is contained in:
2017-06-28 23:54:27 -04:00
parent 2a1975c2c3
commit e8268e1ba5
55 changed files with 4648 additions and 399 deletions

View File

@@ -1,98 +1,62 @@
/* Copyright (c) 2017 Christopher Cromer
* Copyright (c) 2017 Carlos Faúndez
*
* This file is part of mt. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution.
* This file may not be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.
*/
package mt;
import org.w3c.dom.Document;
import java.util.ArrayList;
class Enlace{
char si;
char sj;
char movimiento;
Estado qj;
public Enlace(char si,Estado qj,char sj, char move){
setMovimiento(move);
setSj(sj);
setQj(qj);
setSi(si);
}
private void setSi(char si){
this.si = si;
}
private void setSj(char sj){
this.sj = sj;
}
private void setMovimiento(char movimiento){
this.movimiento = movimiento;
}
private void setQj(Estado qj){
this.qj = qj;
}
@Override
public String toString(){
return ","+si+") = (q"+qj.q+","+sj+","+movimiento+")";
}
}
class Estado{
int q;
ArrayList<Enlace> link;
public Estado(int q) {
this.q = q;
link = new ArrayList<Enlace>();
}
public boolean createLink(char si,Estado qj,char sj, char move){
if(link.isEmpty()) link.add(new Enlace(si,qj,sj,move));
for(int i=0;i<link.size();i++){
if(link.get(i).si == si) return false;
}
link.add(new Enlace(si,qj,sj,move));
return true;
}
@Override
public String toString(){
String _return = "";
for(int i=0; i<link.size();i++){
_return += "(q"+q+link.get(i)+"\n";
}
return _return;
}
}
class Automata {
ArrayList<Estado> estados;
public Automata(Document document){
estados = new ArrayList<Estado>();
Estado aux;
for(int i=0;i<document.getElementsByTagName("transicion").getLength();i++){
char move = document.getElementsByTagName("movimiento").item(i).getTextContent().charAt(0);
if(move == 'E' || move == 'R' || move == 'L' || move == '*'){
int qi = Integer.parseInt(document.getElementsByTagName("qi").item(i).getTextContent());
int qj = Integer.parseInt(document.getElementsByTagName("qj").item(i).getTextContent());
char si = document.getElementsByTagName("si").item(i).getTextContent().charAt(0);
char sj = document.getElementsByTagName("sj").item(i).getTextContent().charAt(0);
/*if(estados.isEmpty() && qi != qj){
estados.add(qi, new Estado(qi));
private ArrayList<Estado> estados;
Automata(Document document) {
setEstados(new ArrayList<>());
for (int i = 0; i < document.getElementsByTagName("transicion").getLength(); i++) {
char move = document.getElementsByTagName("movimiento").item(i).getTextContent().charAt(0);
if (move == 'E' || move == 'R' || move == 'L' || move == '*') {
int qi = Integer.parseInt(document.getElementsByTagName("qi").item(i).getTextContent());
int qj = Integer.parseInt(document.getElementsByTagName("qj").item(i).getTextContent());
char si = document.getElementsByTagName("si").item(i).getTextContent().charAt(0);
char sj = document.getElementsByTagName("sj").item(i).getTextContent().charAt(0);
/*if(estados.isEmpty() && qi != qj){
estados.add(qi, new Estado(qi));
estados.add(qj, new Estado(qj));
}else if(estados.isEmpty() && qi == qj) estados.add(qi, new Estado(qi));*/
if(estados.size() <= qi) estados.add(qi, new Estado(qi));
if(estados.size() <= qj) estados.add(qj, new Estado(qj));
if(!estados.get(qi).createLink(si,estados.get(qj),sj,move)){
if(qi == qj) System.out.println("Recursivo");
else System.out.println("En"+qi+" a "+qj+"Transicion para "+si+" ya esta creada");
}
}else{
System.out.println("Movimiento invalido de cinta");
System.exit(1);
}
}
}
else if(estados.isEmpty() && qi == qj) {
estados.add(qi, new Estado(qi));
}*/
if (estados.size() <= qi) {
estados.add(qi, new Estado(qi));
}
if (estados.size() <= qj) {
estados.add(qj, new Estado(qj));
}
if (!estados.get(qi).createLink(si, estados.get(qj), sj, move)) {
if (qi == qj) {
System.out.println("Recursivo");
}
else {
System.out.println("En" + qi + " a " + qj + "Transicion para " + si + " ya esta creada");
}
}
}
else {
System.out.println("Movimiento invalido de cinta");
System.exit(1);
}
}
}
ArrayList<Estado> getEstados() {
return estados;
}
private void setEstados(ArrayList<Estado> estados) {
this.estados = estados;
}
}

62
src/mt/Enlace.java Normal file
View File

@@ -0,0 +1,62 @@
/* Copyright (c) 2017 Christopher Cromer
* Copyright (c) 2017 Carlos Faúndez
*
* This file is part of mt. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution.
* This file may not be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.
*/
package mt;
class Enlace {
private char si;
private char sj;
private char movimiento;
private Estado qj;
Enlace(char si, Estado qj, char sj, char move) {
setMovimiento(move);
setSj(sj);
setQj(qj);
setSi(si);
}
public char getSi() {
return this.si;
}
private void setSi(char si) {
this.si = si;
}
public char getSj() {
return this.sj;
}
private void setSj(char sj) {
this.sj = sj;
}
public char getMovimiento() {
return this.movimiento;
}
private void setMovimiento(char movimiento) {
this.movimiento = movimiento;
}
public Estado getQj() {
return qj;
}
private void setQj(Estado qj) {
this.qj = qj;
}
@Override
public String toString() {
return "," + si + ") = (q" + qj.getQ() + "," + sj + "," + movimiento + ")";
}
}

50
src/mt/Estado.java Normal file
View File

@@ -0,0 +1,50 @@
/* Copyright (c) 2017 Christopher Cromer
* Copyright (c) 2017 Carlos Faúndez
*
* This file is part of mt. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution.
* This file may not be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.
*/
package mt;
import java.util.ArrayList;
public class Estado {
private final int q;
private final ArrayList<Enlace> enlaces;
Estado(int q) {
this.q = q;
enlaces = new ArrayList<>();
}
ArrayList<Enlace> getEnlaces() {
return enlaces;
}
int getQ() {
return q;
}
boolean createLink(char si, Estado qj, char sj, char move) {
if (enlaces.isEmpty()) {
enlaces.add(new Enlace(si, qj, sj, move));
}
for (Enlace aLink : enlaces) {
if (aLink.getSi() == si) {
return false;
}
}
enlaces.add(new Enlace(si, qj, sj, move));
return true;
}
@Override
public String toString() {
StringBuilder _return = new StringBuilder();
for (Enlace enlace : enlaces) {
_return.append("(q").append(q).append(enlace).append("\n");
}
return _return.toString();
}
}

View File

@@ -7,16 +7,15 @@
package mt;
import java.io.*;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import jdk.internal.org.xml.sax.ErrorHandler;
import jdk.internal.org.xml.sax.SAXException;
import jdk.internal.org.xml.sax.SAXParseException;
import org.w3c.dom.Document;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;
/**
* Esta clase puede abrir y validar un archivo de XML. Se necesita un archivo mtbase.dtd
*/
@@ -30,12 +29,11 @@ class LeerXML {
* @return Devuelve un document de XML o null si hay algun error.
*/
Document leerArchivo(File archivo) {
if(archivo == null){
System.out.println("No se ha seleccionado archivo");
if (archivo == null) {
return null;
}
if (!archivo.exists() || !archivo.getName().endsWith(".xml")) {
System.out.println("Archivo " + archivo.getName() + " no existe o no es compatible");
if (!archivo.exists()) {
MT.mostrarMensaje("Error", "Archivo " + archivo.getName() + " no existe!");
return null;
}
Document dc = createDocument(archivo);
@@ -53,10 +51,10 @@ class LeerXML {
* @return Retorna un document del XML o null si hay algun error.
*/
private Document createDocument(File archivo) {
Document document;
Document documento;
try {
if (!archivo.exists()) {
System.out.println("El archivo " + archivo.getName() + " no existe!");
MT.mostrarMensaje("Error", "Archivo " + archivo.getName() + " no existe!");
return null;
}
@@ -67,12 +65,12 @@ class LeerXML {
DocumentBuilder db = dbf.newDocumentBuilder();
SimpleErrorHandler seh = new SimpleErrorHandler();
db.setErrorHandler(seh);
document = db.parse(archivo);
documento = db.parse(archivo);
if (seh.error) {
return null;
}
document.getDocumentElement().normalize();
return document;
documento.getDocumentElement().normalize();
return documento;
}
catch (Exception e) {
if (e.getMessage().contains(".dtd")) {
@@ -96,12 +94,12 @@ class LeerXML {
if (temp == null) {
return null;
}
Document document = createDocument(temp);
Document documento = createDocument(temp);
if (!temp.delete()) {
System.out.println("No puede borrar el archivo " + temp.getName());
MT.mostrarMensaje("Error", "No se puede borrar el archivo " + temp.getName());
}
if (document != null) {
return document;
if (documento != null) {
return documento;
}
return null;
}

View File

@@ -8,68 +8,58 @@
package mt;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.FileChooser;
import javafx.scene.control.ButtonBar;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.stage.Stage;
import javafx.scene.input.MouseEvent;
import org.w3c.dom.Document;
import java.io.File;
/**
* Esta clase es la clase princial de la Maquina Turing
*/
public class MT extends Application {
/**
* El metodo principal del programa
*
* @param args Los argumentos pasado al programa
*/
public static void main(String[] args) {
launch(args);
}
/**
* Se muestra un mensaje con titulo
*
* @param titulo El titulo de la ventana
* @param mensaje El mensaje
*/
static void mostrarMensaje(String titulo, String mensaje) {
ButtonType botonCerrar = new ButtonType("Cerrar", ButtonBar.ButtonData.OK_DONE);
Dialog<String> dialog = new Dialog<>();
dialog.setTitle(titulo);
dialog.setContentText(mensaje);
dialog.getDialogPane().getButtonTypes().add(botonCerrar);
dialog.getDialogPane().getScene().getWindow().sizeToScene();
dialog.show();
}
/**
* Metodo de JavaFX llamada para generar el interfaz grafico.
* @param primaryStage La ventana principal
* @throws Exception La excepción
*/
@Override
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("mt.fxml"));
primaryStage.setTitle("Maquina de Turing");
static Machine machine;
@Override
public void start(final Stage primaryStage) throws Exception{
//Parent root = FXMLLoader.load(getClass().getResource("mt.fxml"));
Group root = new Group();
primaryStage.setTitle("Maquina de Turing");
primaryStage.setScene(new Scene(root, 300, 275));
Button button = new Button("Elegir archivo");
button.setDefaultButton(true);
button.setLayoutX(130);button.setLayoutY(125);
EventHandler<MouseEvent> eventHandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Abrir archivo XML");
File archivo = fileChooser.showOpenDialog(primaryStage);
LeerXML xml = new LeerXML();
Document document = xml.leerArchivo(archivo);
if(document != null) {
machine = new Machine(document);
for(int i=0; i<machine.machine.estados.size();i++){
System.out.println(machine.machine.estados.get(i));
}
if(machine.comprobarCadena(new StringBuilder("000111###"),5)){
System.out.println("Reconoce");
}else System.out.println("No reconoce");
}
}
};
button.addEventFilter(MouseEvent.MOUSE_CLICKED,eventHandler);
root.getChildren().add(button);
primaryStage.show();
}
/**
* El metodo principal del programa
* @param args Los argumentos pasado al programa
*/
public static void main(String[] args) {
launch(args);
}
Scene scene = new Scene(root, 640, 480);
scene.getStylesheets().add("/mt/mt.css");
primaryStage.setScene(scene);
primaryStage.setMinHeight(480);
primaryStage.setMinWidth(640);
primaryStage.show();
}
}

View File

@@ -1,51 +0,0 @@
/* Copyright (c) 2017 Christopher Cromer
* Copyright (c) 2017 Carlos Faúndez
*
* This file is part of mt. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution.
* This file may not be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.
*/
package mt;
import org.w3c.dom.Document;
public class Machine {
Automata machine;
public Machine(Document document) {
machine = new Automata(document);
}
boolean comprobarCadena(StringBuilder cinta,int estadofinal) {
Estado qi = machine.estados.get(0);
int cabezal = 0;
do{
int i;
for(i=0;i<qi.link.size();i++){
if(qi.link.get(i).si == cinta.charAt(cabezal)){
cinta.setCharAt(cabezal,qi.link.get(i).sj);
switch (qi.link.get(i).movimiento){
case 'L':{
cabezal--;
if(cabezal == (-1)){
cinta.insert(0,"#");
cabezal++;
}
break;
}
case 'R':{
cabezal++;
if(cabezal == cinta.length()) cinta.insert(cabezal,"#");
break;
}
default:{/*Se mantiene*/}
}
qi = qi.link.get(i).qj;
i = -1;
}
}
if(qi.q == estadofinal) return true;
return false;
}while(true);
}
}

55
src/mt/Maquina.java Normal file
View File

@@ -0,0 +1,55 @@
/* Copyright (c) 2017 Christopher Cromer
* Copyright (c) 2017 Carlos Faúndez
*
* This file is part of mt. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution.
* This file may not be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.
*/
package mt;
import org.w3c.dom.Document;
class Maquina {
private final Automata maquina;
Maquina(Document document) {
maquina = new Automata(document);
}
Automata getMaquina() {
return maquina;
}
boolean comprobarCadena(StringBuilder cinta, int estadoFinal) {
Estado qi = maquina.getEstados().get(0);
int cabezal = 0;
int i;
for (i = 0; i < qi.getEnlaces().size(); i++) {
if (qi.getEnlaces().get(i).getSi() == cinta.charAt(cabezal)) {
cinta.setCharAt(cabezal, qi.getEnlaces().get(i).getSj());
switch (qi.getEnlaces().get(i).getMovimiento()) {
case 'L': {
cabezal--;
if (cabezal == (-1)) {
cinta.insert(0, "#");
cabezal++;
}
break;
}
case 'R': {
cabezal++;
if (cabezal == cinta.length()) {
cinta.insert(cabezal, "#");
}
break;
}
default: {/*Se mantiene*/}
}
qi = qi.getEnlaces().get(i).getQj();
i = -1;
}
}
return (qi.getQ() == estadoFinal);
}
}

View File

@@ -0,0 +1,83 @@
/* Copyright (c) 2017 Christopher Cromer
* Copyright (c) 2017 Carlos Faúndez
*
* This file is part of mt. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution.
* This file may not be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.
*/
package mt;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Scene;
import javafx.scene.control.MenuBar;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import org.w3c.dom.Document;
import java.io.File;
import java.net.URL;
import java.util.ResourceBundle;
/**
* Controlar las acciones cuando una opción es elegido en el menu.
*/
public class MenuController extends VBox implements Initializable {
@FXML
private MenuBar menuBar;
/**
* Inicialicar el menu con el idioma.
*
* @param location Tiene URL de FXML en uso.
* @param resourceBundle Tiene recursos qu se pasa al controller.
*/
@Override
public void initialize(URL location, ResourceBundle resourceBundle) {
// No es necesario poner algo aqui porque el programa mt no se usa los resourceBundles
}
/**
* Menu opción cargar transiciones
*
* @throws Exception La excepción
*/
@FXML
protected void cargarTransiciones() throws Exception {
Scene scene = menuBar.getScene();
Stage stage = (Stage) scene.getWindow();
Maquina maquina;
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Abrir archivo XML");
File archivo = fileChooser.showOpenDialog(stage);
LeerXML xml = new LeerXML();
Document documento = xml.leerArchivo(archivo);
if (documento != null) {
maquina = new Maquina(documento);
for (int i = 0; i < maquina.getMaquina().getEstados().size(); i++) {
System.out.println(maquina.getMaquina().getEstados().get(i));
}
TableView tableView = FXMLLoader.load(getClass().getResource("tabla.fxml"));
HBox.setHgrow(tableView, Priority.ALWAYS);
HBox contenido = (HBox) scene.lookup("#contenido");
contenido.getChildren().add(tableView);
TableColumn tableColumn1 = (TableColumn) tableView.getColumns().get(0);
TableColumn tableColumn2 = (TableColumn) tableView.getColumns().get(1);
tableColumn1.setMaxWidth(1f * Integer.MAX_VALUE * 50);
tableColumn2.setMaxWidth(1f * Integer.MAX_VALUE * 50);
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
/*if (maquina.comprobarCadena(new StringBuilder("000111###"), 5)) {
MT.mostrarMensaje("Resultado", "Reconce");
}
else {
MT.mostrarMensaje("Resultado", " No reconce");
}*/
}
}
}

17
src/mt/menu.fxml Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2017 Christopher Cromer
Copyright (c) 2017 Carlos Faúndez
This file is part of mt. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution.
This file may not be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.
-->
<?import javafx.scene.control.*?>
<MenuBar xmlns:fx="http://javafx.com/fxml/1" fx:id="menuBar" fx:controller="mt.MenuController" xmlns="http://javafx.com/javafx/8.0.92">
<Menu text="Operaciones">
<MenuItem text="Cargar transiciones ..." onAction="#cargarTransiciones"/>
<MenuItem text="Reconocimiento indiviudal ..." disable="true" onAction="#cargarTransiciones"/>
<MenuItem text="Reconocimiento por lote ..." disable="true" onAction="#cargarTransiciones"/>
</Menu>
</MenuBar>

15
src/mt/mt.css Normal file
View File

@@ -0,0 +1,15 @@
/* Copyright (c) 2017 Christopher Cromer
* Copyright (c) 2017 Carlos Faúndez
*
* This file is part of mt. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution.
* This file may not be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.
*/
.text {
-fx-font-family: "Arial";
-fx-font-size: 14;
}
.scroll-pane {
-fx-background-color: transparent;
}

View File

@@ -1,3 +1,19 @@
<GridPane fx:controller="mt.Controller"
xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10">
</GridPane>
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2017 Christopher Cromer
Copyright (c) 2017 Carlos Faúndez
This file is part of mt. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution.
This file may not be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.
-->
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<VBox xmlns:fx="http://javafx.com/fxml/1" prefHeight="480.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/8.0.92">
<fx:include source="menu.fxml"/>
<ScrollPane fitToHeight="true" fitToWidth="true" VBox.vgrow="ALWAYS">
<HBox alignment="CENTER" VBox.vgrow="ALWAYS" fx:id="contenido">
</HBox>
</ScrollPane>
</VBox>

18
src/mt/tabla.fxml Normal file
View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2017 Christopher Cromer
Copyright (c) 2017 Carlos Faúndez
This file is part of mt. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution.
This file may not be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.
-->
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.GridPane?>
<TableView xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.92" fx:id="tableView" GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS" GridPane.columnIndex="0" GridPane.rowIndex="0">
<columns>
<TableColumn fx:id="columna1" sortable="false" editable="false" text="(qi,si)"/>
<TableColumn fx:id="columna2" sortable="false" editable="false" text="(qj,sj,movimiento)"/>
</columns>
</TableView>