Mostrando entradas con la etiqueta Programación. Mostrar todas las entradas
Mostrando entradas con la etiqueta Programación. Mostrar todas las entradas

5 may 2013

Caja registradora en Java con base de datos Access utilizando el IDE Netbeans

Después de prácticamente 2 meses sin publicar absolutamente nada os quiero hacer llegar este trabajo de un curso de programación Java que he estado realizando (de ahí mi baja frecuencia de publicación). Se basa en un programa que hace las veces de caja registradora moderna y que permite guardar datos de información de clientes y de pedidos en una base de datos Access. A continuación se muestra una memoria explicativa.



1.     Diseño de la base de datos

El objetivo es crear una aplicación que permita de información relacionada con los pedidos que en una compañía de comida rápida se hacen. Debe permitir la opción de registrar clientes y que estos tengan descuentos. Para el diseño de la base de datos hay que determinar primero cuáles serán las entidades y los atributos asociados a dichas entidades. Se han considerado como entidades los Clientes, los Pedidos y los Productos. Cada uno de ellos debe tener unos atributos, que representan la información sobre dichas entidades. Los atributos que se almacenan de cada entidad son:
·         Entidad Cliente: NIF, Nombre, PrimerApellido y SegundoApellido.
·         Entidad Pedidos: NúmeroPedido, Fecha e Importe.
·         Entidad Productos: NúmeroProducto, Precio y NombreProducto.
Decididas las entidades y atributos asociados, es necesario determinar los atributos claves, aquellos que no se repiten y no pueden estar vacíos. Se han elegido los siguientes:
·         Entidad Cliente: NIF.
·         Entidad Pedidos: NúmeroPedido.
·         EntidadProductos: NúmeroProducto. En este atributo clave hay que aclarar que aunque se vayan a servir productos iguales, no se estarán sirviendo los mismos productos. Es decir, si un cliente pide un capuccino, eso será un producto, y si justo después otro cliente pide de nuevo capuccino, está pidiendo otro capuccino nuevo, no el mismo que se entregó al cliente anterior, por lo que nunca habrá dos capuccinos con el mismo NúmeroProducto.
Llegados a este punto es hora de determinar las relaciones entre entidades. Se han considerado las siguientes:
·         Un Cliente realiza Pedidos, de forma que las entidades Cliente y Pedidos se relacionan y tienen una relación uno a muchos, ya que un cliente puede realizar muchos pedidos, pero un determinado pedido es realizado por un solo cliente.
·         Un Pedido estará formado por uno o varios Productos, teniéndose así una relación uno a muchos, ya que un Pedido puede tener varios Productos, pero cada Producto (NúmeroProducto) pertenece a un solo pedido.
Por último queda por determinar las claves foráneas, traspasando así el atributo clave de una entidad a otra, existiendo así elementos de unión entre entidades relacionadas. Las claves foráneas que se han determinado son:
·         Entidad Cliente: Ninguna.
·         Entidad Pedidos: NIF (procedente de la entidad Cliente).
·         Entidad Productos: NúmeroPedido (procedente de la entidad Pedidos).
Con toda esta información recabada, ya es posible generar el modelo E-R de forma gráfica, que se muestra en la imagen a continuación:

Modelo ER de la base de datos

2.     Diseño de la interfaz

Para el diseño de la interfaz se ha optado por buscar la simplicidad y facilidad de uso, tratando de crear un sistema Poka-Yoke que evite errores en la lectura-introducción de datos por parte del usuario de la aplicación.
Toda la aplicación parte de una ventana principal sobre la que aparecen-desaparecen paneles según se vaya indicando. Al arrancar el programa principal aparecerá esta ventana principal, que tiene el siguiente aspecto:
Aspecto de la ventana principal
En ella se puede observar lo que podría ser el logotipo de la compañía (evidentemente se ha escogido uno cualquiera), un título y un menú en la parte superior que permite acceder a todas las funcionalidades del programa.
Clicando en la opción Cliente podemos acceder al alta, baja y modificación de clientes. Las ventanas se muestran a continuación respectivamente:
Aspecto de la ventana AltaCliente
Aspecto de la ventana BajaCliente
Aspecto de la ventana ModificarCliente
Todas ellas están formadas por etiquetas, cajas de texto sobre las que introducir la información y botones que captarán eventos para ejecutar acciones.
Desde el menú Pedidos se puede acceder a las opciones Nuevo pedido, Fecha pedidos, Pedidos de clientes, cuyos nombres resultan autoexplicativos. Los aspectos de dichas ventanas son:
Apecto de la ventana AltaPedido
Esta es la parte de la interfaz más recargada. En la parte superior izquierda aparecen las etiquetas y cajas de texto que permiten introducir la fecha actual (en un programa real debiera captarlo automáticamente) e introducir el NIF de un cliente si está registrado, o bien realizar el pedido como un cliente no registrado. Debajo de estas opciones se encuentran los diferentes productos que componen el menú, cada uno de ellos con un botón que permite añadir al pedido el producto. En la parte derecha se muestra una tabla sobre la que irán apareciendo los productos que un cliente solicita, una opción de eliminar algún tipo de producto en caso de introducción por error y por último una caja de texto que muestra el importe total y el botón para imprimir o realizar el pago del pedido.
Aspecto de la ventana FechaPedidos
Esta es una ventana simple sobre la que introducir la fecha sobre la cuál queremos ver los pedidos realizados.
Aspecto de la ventana PedidosCliente
Muy similar a la anterior, esta ventana permite introducir el NIF del cliente sobre el que queremos ver los pedidos que ha solicitado.

3.     Diseño de la arquitectura de programación

Para la realización del programa se han generado los siguientes paquetes:
·         fastfoodcompany.principal: Contiene Aplicación y FastFoodCompany. Aplicación simplemente se encarga de cargar y visualizar la ventana principal, que está diseñada en FastFoodCompany.
·         fastfoodcompany.principal.acciones: Contiene la clase AccionesFastFoodCompany que se encarga de atender a los eventos que ocurran en la ventana FastFoodCompany y realizar las acciones necesarias.
·         fastfood.clientes: Contiene AltaCliente, BajaCliente y ModificarCliente que son las clases con los JPanel (paneles) vistos en las figuras 3, 4 y 5.
·         fastfood.clientes.acciones: Contiene las clases AccionesAltaCliente, AccionesBajaCliente y AccionesModificarCliente que, al igual que hace AccionesFastFoodCompany, se encarga de atender a los eventos que ocurran en las ventanas (que serán originados por el usuario) y ejecutar las respuestas.
·         fastfood.pedidos:Contiene AltaPedido, FechaPedidos y PedidosCliente.
·         fastfood.pedidos.acciones: Con AccionesAltaPedido, AccionesFechaPedidos y AccionesPedidosCliente.
·         fastfood.gestionBD: Contiene ServiceCliente, GestionSQLClientes, ServicePedidos y GestionSQLPedidos. Las clases GestionSQLXXX se encargan de gestionar la conexión con la base de datos, mientras que las clases ServiceXXX se encarga de generar las consultas SQL correspondientes que luego serán solicitadas desde GestionSQLXXX. Las clases XXXCliente se encargan de todo lo relacionado con el alta, baja y modificación de clientes, mientras que XXXPedidos gestionan lo relacionado con los pedidos.
Se ha desarrollado por tanto una arquitectura Model-View-Controller, donde:
  • View: FastFoodCompany, AltaCliente, BajaCliente, ModificarCliente, AltaPedido, FechaPedidos y PedidosCliente.
  • Model: AccionesFastFoodCompany, AccionesAltaCliente, AccionesBajaCliente, AccionesModificarCliente, AccionesAltaPedido, AccionesFechaPedidos, AccionesPedidosCliente, ServiceClientes y ServicePedidos.
  • Controller: GestionSQLClientes, GestionSQLPedidos.

4.     Manual de usuario interactivo

Véase:
Manual usuario interactivo

5.     Código fuente de la aplicación

Lo podéis descargar aquí





21 ene 2013

¿Cursando Fundamentos de programación en la UNED? Tengo un regalo para tí. Parte 3 y última

Pues después de mucho batallar y gracias a la inestimable ayuda de compañeros que me han resuelto dudas en el foro y de otra persona que sabrá perfectamente quién es cuando lo lea, he conseguido terminar esta última práctica. Como buen español, dejándolo para el final. Espero que, aunque sea bastante tarde os sirva. Estoy bastante cansado, así que, sin más, cuelgo el enlace
Práctica 4

19 ene 2013

Borrador práctica 4 de fundamentos de programación

Hola a tod@s. Como muchos de los que habéis seguido este blog sabréis, he ido incluyendo aquí los resultados de las prácticas de fundamentos de programación. Antes de incluirlas, siempre me había cerciorado bien de que estuviesen correctas (aunque no optimizadas). Sin embargo, debido al gran retraso que llevo con esta 4º y última, y tras dedicarle bastante tiempo sin obtener ningún resultado satisfactorio, he decidido colocar un borrador de mi estado actual. Lo comento aquí y luego añado el código.
La idea es tener un programa principal que se ejecuta continuamente hasta que se pulsa la opción salir. Para la gestión de las reservas utilizo tipos de datos definidos. Un tipo de datos denominado "TipoReserva" que contiene la "sala" (tipo int), la "fecha" (otro tipo definido formado por 3 tipos int) y el nombre de la "persona" que la realiza. Como podemos realizar hasta 100 reservas, pues creo he creado un tipo de datos llamado "TipoVectorReservas" que simplemente consta de 100 "TipoReserva". Cuando quiero introducir una reserva, hago que la información (previamente comprobada) se almacene en ese vector. Si quiero eliminar una reserva, leo los datos de la reserva a eliminar y la elimino de ese "vectorReservas". Por último, si quiero listar las reservas de un determinado mes, leo los datos necesarios y los paso como argumento a una función llamada ImprimirCalendario. Hubo momentos en los que he conseguido compilar el código y comprobé que obtenía resultados, no los esperados, pero resultados. Sin embargo debí hacer alguna modificación y desde entonces soy incapaz. 
Siento no haber podido colgarla ya funcionando correctamente. De cualquier forma espero que os pueda servir.
Borrador de la práctica
Actualización: He estado modificando y tratando de limpiar el código y creo que el nuevo borrador que tengo parece mejor, aunque sigo obteniendo errores de compilación que no consigo resolver. Podéis encontrarlo aquí
Borrador 1 de la práctica

24 nov 2012

¿Cursando fundamentos de programación en la UNED? Tengo un regalo para tí. Parte 2.

Hola a todos aquellos interesados y cursando la asignatura de fundamentos de programación de la UNED. Con dos días de retraso con respecto a la fecha indicada en el planning, publico una solución a la práctica 3. El programa imprime la hoja de calendario correspondiente a un mes comprendido entre Enero de 1601 y Diciembre de 3000.
El código se encuentra comentado para una fácil comprensión. Espero que os sea de ayuda. Simplemente decir que no encontré un mecanismo en condiciones para el procedimiento que imprime el calendario, así que al final me decanté por hacerlo utilizando el comando "printf" tantas veces como fuera necesario.
El código fuente lo podéis encontrar aquí.

Recordar que las dos primeras prácticas las podéis encontrar aquí

22 nov 2012

Crear una base de datos básica de clientes en Java

Unos pocos días atrás creé una entrada en la cuál mostraba una base de datos para clientes (por ejemplo) que había creado utilizando el software y lenguaje de programación Gambas. Si bien en aquel programa utilizaba una base de datos SQLite para almacenar los datos, en este programa se almacena en la memoria del ordenador. Quedo por lo tanto en mi lista de tareas el realizar la base de datos en Java almacenando datos en un servidor. 
La aplicación consiste en una ventana principal que contiene una tabla que muestra la lista de clientes guardados. Esa ventana permanece hasta que se realiza alguna de las tres acciones posibles, que son dar de alta a un nuevo cliente, modificar un cliente o dar de baja a un cliente previamente almacenado. Al elegir la opción de alta de un nuevo cliente aparecerá sobre la ventana principal un nuevo panel con cuadros de texto para introducir los datos y el botón de guardar. En caso de que la opción elegida sea modificar o borrar un cliente, el panel que aparecerá contendrá cuadros de texto para buscar un determinado cliente y además otros cuadros de texto que muestran el cliente sobre el que realizar la opción que se desee. Personalmente pienso que la interfaz que he creado es bastante mejorable, pero la utilidad y funcionalidad que quería darle las tiene.
Decir que la lista de clientes almacenados se guarda en un ArrayList. Encontré información muy interesante con respecto a este tipo de elementos aquí. Como de cada cliente se almacena el nombre y los dos apellidos, pues la lista está formada por conjuntos de ArrayList, teniendo por tanto una lista ArrayList<ArrayList<String>>. Para recorrer los elementos de la lista he utilizado un ListIterator, y para buscar un determinado cliente el método de ArrayList "contains". Podeis ver y descargar el código fuente en el enlace al final de la entrada.

Aspecto de la ventana principal

Aspecto al seleccionar la opción de alta de cliente

Aspecto de la ventana añadiendo nuevos clientes

Ventana de modificar cliente con cuadros de búsqueda

 Podéis descargar el código fuente desde aquí.



17 nov 2012

¿Cursando fundamentos de programación en la UNED? Tengo un regalo para tí.

Actualmente estoy cursando la asignatura Fundamentos de Programación del Grado de Ingeniería Informática de la UNED. Para el que también esté cursándolo, sabrá que hay una parte práctica de la asignatura consistente en 4 prácticas. Por si os puede servir de ayuda, voy a tratar de colgar todas, con comentarios para que puedan entenderse, aquí en mi blog. De momento, puedes encontrar las dos primeras aquí. Espero que os sirva...

Actualización 1: Ya se encuentra disponible la práctica 3. La podéis encontrar aquí.

11 nov 2012

Crear una base de datos de clientes en Gambas

Continuo mi andadura con la programación en Gambas, y esta vez le toca el turno a las bases de datos, con las que también estoy trabajando en Java. Siguiendo el libro de Gambas de Daniel Campos y José Luis Redrejo he creado una base de datos para clientes. Utiliza una SQLite aunque cuando realice la aplicación en Java lo haré con MySQL, que parece más extendida y trabaja utilizando un servidor.
La aplicación se encarga de mostrar una lista de los clientes actuales en una ventana principal y añade las opciones de añadir, modificar o borrar. Para la opción añadir se abre una nueva ventana para introducir los caracteres. 
Con respecto al libro citado anteriormente tuve que realizar distintas modificaciones, bien porque la versión actual de Gambas (3.3.3) difiere de la utilizada para el libro, o bien porque mi aplicación, aunque parecida, tiene algunas diferencias. En el siguiente vídeo se muestra el proceso de creación de una nueva base de datos, que parece ser una opción que a muchos usuarios les cuesta encontrar

El aspecto de la ventana principal cuando aún no hay datos de ningún cliente es
Aspecto general de la aplicación

Mientras que con datos ya introducidos pasa a ser
Aspecto con datos introducidos

Esta es la ventana para añadir o modificar de la base los datos de un cliente
Ventana para añadir o modificar cliente
Podéis descargar el código fuente y el archivo ejecutable aquí

8 nov 2012

Tratando de entender y utilizar alguna API

Desde hace tiempo llevo leyendo el blog de atareao, que es un blog dedicado a Ubuntu y software libre. Uno de los logros que me parecen más interesantes de entre los que este bloguero ha creado son las lentes para Ubuntu, entre ellas Yavol. Tan interesantes me parecieron, que quise informarme sobre cómo las había hecho. Fue ahí donde conocí el concepto de API, que me interesó tanto que quedó en mi recámara guardado para cuando tuviese tiempo, intentar usar alguna.
Actualmente estoy en la parte final de un curso de programación Java utilizando el entorno de programación multiplataforma Netbeans. Así que se me ocurrió la idea de generar una aplicación gráfica con netbeans utilizando la API de Google Translate. Busqué algo de información que me sirviese como punto de partida y encontré información tan interesante como la que podéis ver aquí en un screencast. Así que me puse manos a la obra y pronto obtuve resultados, pero no los esperados (más adelante comentaré por qué). En la siguiente imagen podéis ver el aspecto gráfico de la apliación creada
Aspecto gráfico de la aplicación

El código tuve que modificarlo con respecto al que se incluye en el screencast del enlace anterior, ya que utilicé una versión de la API  más reciente. El código completo lo podéis encontrar debajo

import com.google.api.translate.*;  //Importa todas las clases de la api

public class ApiJava extends javax.swing.JFrame {

    /**
     * Creates new form ApiJava
     */
    public ApiJava() {
        initComponents();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        panelContenedor = new javax.swing.JPanel();
        txtEspanol = new javax.swing.JTextField();
        btnTraducir = new javax.swing.JButton();
        txtIngles = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        panelContenedor.setName("Traductor básico"); // NOI18N

        txtEspanol.setPreferredSize(new java.awt.Dimension(40, 20));

        btnTraducir.setText("Spa->Eng");
        btnTraducir.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnTraducirActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout panelContenedorLayout = new javax.swing.GroupLayout(panelContenedor);
        panelContenedor.setLayout(panelContenedorLayout);
        panelContenedorLayout.setHorizontalGroup(
            panelContenedorLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panelContenedorLayout.createSequentialGroup()
                .addComponent(txtEspanol, javax.swing.GroupLayout.PREFERRED_SIZE, 87, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btnTraducir)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(txtIngles, javax.swing.GroupLayout.DEFAULT_SIZE, 80, Short.MAX_VALUE))
        );
        panelContenedorLayout.setVerticalGroup(
            panelContenedorLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panelContenedorLayout.createSequentialGroup()
                .addGap(15, 15, 15)
                .addGroup(panelContenedorLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(panelContenedorLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(txtEspanol, javax.swing.GroupLayout.DEFAULT_SIZE, 34, Short.MAX_VALUE)
                        .addComponent(btnTraducir))
                    .addComponent(txtIngles)))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(panelContenedor, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(panelContenedor, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 12, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>

    private void btnTraducirActionPerformed(java.awt.event.ActionEvent evt) {                                            
        
        try {
            String textoOriginal=(String)this.txtEspanol.getText(); //Recoge el texto
            Translator traslador=new Translator();  //Instancia un objeto de la clase Translator
            String textoTraducido=traslador.translate(textoOriginal, Language.SPANISH, Language.ENGLISH);
            //Convierte el texto original de Spanish a English y lo almacena
            //en textoTraducido
            this.txtIngles.setText(textoTraducido); //Enviamos el textoTraducido a la caja de texto
        }catch (Exception e){   //Chequea excepciones
            System.out.println("Error"+e.getMessage());
        }
    }                                           

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(ApiJava.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(ApiJava.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(ApiJava.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(ApiJava.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new ApiJava().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify
    private javax.swing.JButton btnTraducir;
    private javax.swing.JPanel panelContenedor;
    private javax.swing.JTextField txtEspanol;
    private javax.swing.JTextField txtIngles;
    // End of variables declaration
}


Cuando todo estaba perfectamente compilado y parecía listo para funcionar, la ejecución de la aplicación me devolvió el siguiente error

Can't parse the response from Google Translate service into JSON object
org.json.JSONException: JSONObject["responseData"] is not a JSONObject.


Tras una búsqueda por internet averigué que este error está relacionado con que ahora la API  de Google Translate es de pago, así que todo mi esfuerzo se fue por la borda porque por simple curiosidad no voy a pagar para usarla.
En un futuro tengo pensado utilizar alguna otra, esta vez cerciorándome de que es gratuita. De momento he pensado en la de OpenStreetMap. ¿Me recomendáis alguna?

4 nov 2012

Desarrollando una aplicación gráfica para apagar el sistema automáticamente

Hay comandos en GNU/Linux que permites realizar un apagado de nuestro sistema. Este apagado se puede hacer, bien indicando en cuántos minutos queremos que se apague, o bien indicando la hora. Si queremos la opción de minutos restantes:
shutdown -h minutos
Mientras que si preferimos indicar la hora:
shutdown -h hh:mm
En caso de haber introducido la opción de apagado automático y que queramos cancelarla:
shutdown -c
Utilizando estos comandos y la potencia de gambas podemos desarrollar fácilmente una aplicación gráfica que permita el apagado del sistema. Veámos cómo hacerlo. 
Lo primero es crear el diseño de nuestra aplicación. En mi caso he decidido no esmerarme mucho, y el resultado obtenido es 
Aspecto visual
En esta ventana tenemos la opción de elegir ambos tipos de apagado y además nos muestra el comando que se envía en consola. Por simplicidad a la hora de realizar la programación, requiere que en el caso de elegir la opción "Apagar a las" se introduzcan dos dígitos en cada recuadro y que los valores sean válidos. A continuación se muestran ejemplos con las diferentes opciones en funcionamiento
Ejecutando la opción "Apagar en"

Ejecutando la opción "Apagar a las"

Ejecutando la opción "Cancelar apagado"
El código que ejecuta esta aplicación es


' Gambas class file

Public minutosRestantes As String
Public minutos As String
Public hora As String
Public comando As String
Const cancelar As String = "gksu -l shutdown -c"
Const apagar As String = "gksu -l shutdown -h "

Public Sub _new()

End

Public Sub Form_Open()

End

Public Sub btnCancelar_Click()

  comando = cancelar  'Asignamos como comando la opción cancelar
  txtComando.text = comando
  Shell comando 'Enviamos el comando a la shell
  

End

Public Sub btnAceptar_Click()

  If rdbCuentaAtras.value = True Then   'Comprueba si el boton de cuenta atras esta activo
    minutosRestantes = vlbMinutosRestantes.Text   
    comando = apagar & minutosRestantes   'Si lo está, envía el comando de cuenta atrás
    txtComando.text = comando
    Shell comando
  Else 'Si no lo esta, entonces se envia la hora a la cual queremos apagar la computadora
    hora = vlbHora.Text
    minutos = vlbMinutos.Text
    comando = apagar & hora & ":" & minutos  'Concatena para formar el comando
    Shell comando
    txtComando.text = comando
  Endif  '

End

Gambas y el comando "shell"

Shell es un intérprete de comandos que permite controlar el funcionamiento de la computadora. En GNU/Linux disponemos de la terminal, con la cuál podemos, introduciendo los comandos en modo texto, acceder al sistema.
Indagando un poco en el foro de gambas en español me he percatado de una posibilidad que ofrece esta herramienta que aumenta exponencialmente las posibilidades a la hora de crear programas. Y no es otra cosa que el comando SHELL que se encarga de pasar un comando al sistema. Una guía de comandos la podemos encontrar en el tutorial Linux de tecnum  o en la documentación de Ubuntu en español. Veamos un ejemplo simple que, aunque a priori no muestre toda la grandeza de este comando de gambas, permite dar una idea. El ejemplo consiste en actualizar nuestro sistema. Aunque existe aplicaciones gráficas que permiten hacer esto, también se puede hacer, como todo desde la terminal, de la forma que se muestra a continuación
Evidentemente, es un método que requiere conocer los comandos y que para el usuario puede resultar complejo. Sin embargo, esto mismo se puede hacer gráficamente con una aplicación muy simple. Consiste en un simple botón que al ser pulsado se produce el envío de ese comando a la shell. La interfaz gráfica es
Pulsando este botón se ejecutará la actualización del sistema. El código el siguiente

' Gambas class file

Public Sub _new()
End

Public Sub Form_Open()
End

Public Sub btnActualizar_Click()
Shell "gksu -l apt-get update && gksu -l apt-get upgrade" Wait
End

Como podéis observar el código resulta bastante sencillo. Pronto espero publicar una aplicación más interesante... el apagado automático del sistema.

3 nov 2012

¿Algún visual basic para linux? Sí, Gambas

Llevo unos meses dedicando tiempo a la programación. Aunque ya tenía conocimientos previos, eran muy básicos, así que decidí dar un empujón al tema. Si has leído la entrada anterior, habrás observado que uno de los tutoriales que podemos encontrar en tecnum está dedicado a Visual Basic, que es para principiantes una de las opciones más adecuadas. Este software permite implementar aplicaciones gráficas en muy poco tiempo. Al estar dirigido a sistemas Windows, decidí buscar algún equivalente para Linux. La respuesta la encontré rápido: Gambas. Aunque hace un tiempo escuché acerca de este proyecto, pensé que estaría actualmente abandonado. Nada más lejos de la realidad, han sacado a la luz tres versiones en aproximadamente un mes. Así que me decidí a probarlo. Si bien la interfaz puede dejar mucho que desear visualmente hablando, cumple con el cometido que andaba buscando, crear programas básicos con facilidad. Sin embargo, gambas utiliza un lenguaje muy parecido a Basic, que era hasta ayer desconocido para mí. Así que se me ocurrió la idea de comenzar a adquirir conocimientos de Basic utilizando el tutorial de tecnum y combinarlo con Gambas. Los resultados me parecen interesantes, el ritmo de aprendizaje muy bueno. También busqué algún tipo de tutorial dedicado especialmente a gambas. Fruto de esta búsqueda encontré el portal Comunidad Gambas-es, en el cuál se incluye una sección de descargas de manuales, entre ellos uno de Daniel Campos y José Luis Redrejo más que interesante (puedes descargarlo desde aquí). Combinando toda esta información me propuse realizar un primer ejemplo. A continuación voy a explicar mi primer proyecto, basado en un ejemplo calculadora muy elemental  incluido en el curso de Visual Basic. Basta con arrancar la aplicación, seleccionar la opción de generar una nueva aplicación gráfica, dar un nombre a nuestro proyecto y ya nos encontramos con algo como esto
Que viene a ser una interfaz, si bien no muy buena estéticamente, con una estructura y opciones parecidas a las que nos podamos encontrar en Visual Basic de versiones antiguas. Añadiendo los elementos necesarios a la ventana principal obtenemos
Con la interfaz ya diseñada, resta por añadir un poco de código en el Main para hacer funcional el programa

' Gambas class file

Public Sub _new()
End

Public Sub Form_Open()
End

Public Sub btnSuma_Click()
  vlbResultado.Text = Val(vlbOperando1.Text) + Val(vlbOperando2.Text)
  txtOperacion.Text = "+"
End

Public Sub btnResta_Click()
  vlbResultado.Text = Val(vlbOperando1.Text) - Val(vlbOperando2.Text)
  txtOperacion.Text = "-"
End

Public Sub btnMultiplicacion_Click()
  vlbResultado.Text = Val(vlbOperando1.Text) * Val(vlbOperando2.Text)
  txtOperacion.Text = "*"
End

Public Sub btnDivision_Click()
  vlbResultado.Text = Val(vlbOperando1.Text) / Val(vlbOperando2.Text)
  txtOperacion.Text = "/"
End
El resultado obtenido es
Espero que les haya gustado...

Colección aprenda como si estuviera en primero de Tecnum, Universidad de Navarra

Para iniciarse en el mundo de la programación, unos tutoriales de calidad siempre ayudan. Una colección de apuntes como apoyo a la docencia fueron creados por profesores y colaboradores de la Escuela Superior de Ingenieros de San Sebastián. Como indican en el sitio web de tecnum, no se suponen conocimientos previos. Además esta colección puede ser descargada como ficheros .pdf. A mí no me queda más que agradecer el esfuerzo realizado, me parece simplemente genial. La colección la pueden encontrar aquí, existiendo tutoriales para herramientas tan utilizadas como Visual Basic o Java.