Thursday, June 20, 2013

NUESTRO SERVIDOR WEB EN CASA

Lo primero es adentrarnos en el desarrollo de aplicaciones web; para esto necesitamos entender conceptos como html, javascript, jquery, jquery mobile y otros mas que se apareceran por el camino.

Instalemos el ambiente de desarrollo que necesitamos; descarguemos de la web la utileria XAMPP
(http://www.apachefriends.org/es/xampp.html). Esta utileria, una vez descargada; se descomprime y ejecuta.

Con esto contaremos con un servidor web en nuestro propio equipo en el que podremos trabajar y desarrollar aplicaciones web.
Si seguimos las instrucciones de instalación y todo sale bien, al escribir la direccion http://localhost en el explorador web de nuestra preferencia (Internet Explorer, Google Chrome, Firefox Mozilla, Opera, etc) veremos la siguiente pantalla.


Y con esto podremos empezar nuestro camino, en la próxima edición veremos un sencillo HOLA MUNDO, veremos en el camino el html, jquery, jquery mobile; los cuales serán la base para veamos lo que es phonegap y su uso para la creación de aplicaciones Android. 

Por hoy es todo, y nos veremos en la próxima.

EL RETORNO DE LA ETERNIDAD

Bueno, hemos estado un poco lejos de lo que es seguir colaborando en este blog.

En el ultimo capitulo veíamos como crear aplicaciones para dispositivos moviles utilizando las bondades del lenguaje Java, y mas específicamente. el J2ME.... pues el Mundo ha dado algunas vueltas desde entonces; empezando por el hecho que Java con todas sus modalidades y presentaciones ha pasado a formar parte de la familia Oracle.

Y aunque esto ha representado, en mi humilde opinión, un retraso en la evolución del Java; también han surgido nuevos paradigmas y necesidades, así como herramientas y opciones dentro del desarrollo de aplicaciones movibles.

Ahora el Mundo gira interconectado los unos con los otros, de alli que ahora las aplicaciones móviles deben planear dentro de la Nube; interactuando con redes sociales, webservices, accesos remotos a la información relevante y claro, por supuesto, a una total independencia entre dispositivo y aplicación. Esto es, que el desarrollo de la aplicacion depende aun menos del dispositivo en el que se va a ejecutar.

Por esto ahora que hemos regresado a seguir colaborando en este blog, nos pondremos al dia para seguir con nuestro trabajo de desarrollo.

Thursday, November 27, 2008

BAJEMOS A ECHAR UN VISTAZO


INTERFACES DE BAJO NIVEL

Bueno, en las entregas anteriores hablamos de las interfaces de alto nivel; comentábamos que estas interfaces son de las más fáciles de implementar pues su presentación gráfica queda a cargo del dispositivo en que se ejecute la aplicación.
Esto nos permite ahorrar tiempo y esfuerzo, aunque en ocasiones será necesario tomar el control de la presentación, por ejemplo: Si lo que estamos desarrollando es un videojuego.

REGLA No. 1:
Antes de comenzar, es conveniente que establecer una regla : "Todas las pantallas que vayamos a crear usando las APIs de bajo nivel heredan de la clase Canvas".

Por esta razón, lo primero de todo es conocer a fondo esta clase y luego iremos profundizando en cada uno de los elementos que la componen.
La clase Canvas es la superclase de todas las pantallas que usan las APIs de bajo nivel, al igual que Screen lo era para las pantallas que usaban las APIs de alto nivel.

CONVIVENCIA PACIFICA:
Sin embargo, en la relación de APIs de alto y bajo nivel, no hay nada escrito, ésto es : "No existe ningún impedimento que nos permita usar en el mismo MIDlet pantallas tanto derivadas de Canvas como de Screen"

La clase Canvas permite manejar eventos de bajo nivel y dibujar cualquier cosa por pantalla. Es por ésa razón que se usa como base para la realización de juegos.

Esta clase posee un método abstracto paint() que debemos implementar de manera obligatoria (Por nuestra propia voluntad) y es la encargada de dibujar en la pantalla del dispositivo.


Veamos un ejemplo para irnos familiarizando:


BajoNivel.java


import java.io.IOException;
import javax.microedition.lcdui.*;
public class BajoNivel extends Canvas implements CommandListener {
private PBajoNivel midlet;
private Command salir;
private Image imgFondo, imgTriste;
public BajoNivel(PBajoNivel mid) {
try {
imgFondo = Image.createImage("/fondo.PNG");
imgTriste = Image.createImage("/triste.PNG");
} catch (IOException e) {
e.printStackTrace();
}
salir = new Command("Salir", Command.EXIT,1);
this.midlet = mid;
this.addCommand(salir);
this.setCommandListener(this);
}
public void paint(Graphics g) {
g.setColor(255,255,255);
g.fillRect(0,0,getWidth(),getHeight());
g.setColor(0,0,0);
g.drawImage(imgFondo, 0, 0, 0);
g.drawImage(imgTriste, 40, 40, 0);
}
public void commandAction(Command c, Displayable d){
if (c == salir){
midlet.salir();
}
}
}



Esta rutina es la que nos mostrará en el dispositivo la pantalla, nótese que estamos utilizando dos imágenes fondo.PNG y triste.PNG, estos archivos los colocamos en el directorio de RES en nuestro proyecto.


Ahora veamos el código del MIDlet que lo mandará llamar.


PBajoNivel.java
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class PBajoNivel extends MIDlet {
private BajoNivel panCanvas;
private Display pantalla;
public PBajoNivel() throws Exception{
pantalla = Display.getDisplay(this);
panCanvas = new BajoNivel(this);
}
public void startApp() {
pantalla.setCurrent(panCanvas);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
public void salir(){
destroyApp(false);
notifyDestroyed();
}
}


Como se observa, PBajoNivel.java se limita a declarar un objeto pancanvas heredado de la clase BajoNivel.


Veamos dos ejemplos de ejecutar ésta aplicación en dos modelos distintos de cellular, a fin de que el lector pueda constatar la diferencia de despliegue entre uno y el otro.












Sunday, November 23, 2008

EL RESTO DE LAS INTERFACES

En las útimas dos entregas, hemos visto el uso de dos componentes para el uso de menús, vimos la clase LIST y CHOICEGROUP; vimos que básicamente la diferencia entre ambas es que la clase LIST no está subordinada a la clase FORM; ésto es, que no es necesario crear primero un objeto tipo FORM para luego agregar el objeto LIST.



private Display display;

private List miLista;

...

display = Display.getDisplay(this);

miLista = new List("Opciones", List.IMPLICIT);
miLista.append("Altas", null);
miLista.append("Bajas", null);
miLista.append("Consultas", null);
miLista.append("Modificaciones", null);
miLista.append("Impresion", null);
...


display.setCurrent(miLista);



Mientras que un objeto CHOICEGROUP debe estar unido a un objeto FORM.



private Display miDisplay;
private Form miForma;
private ChoiceGroup miGrupo;


...

miDisplay = Display.getDisplay(this);
miForma = new Form("MENU PRINCIPAL");


...

miGrupo = new ChoiceGroup("Opciones: ", ChoiceGroup.EXCLUSIVE);
miGrupo.append("Altas", null);
miGrupo.append("Bajas", null);
miGrupo.append("Consultas", null);
miGrupo.append("Modificaciones", null);
miGrupo.append("Impresion", null);


...

miForma.append(miGrupo);

...
display.setCurrent(miLista);




Pero además de estas clases contamos con muchas otras más como...


Class Ticker

Util para mostrar mensajes en forma de una marquesina deslizándote lado a lado de la pantalla del usuario.


Class DateField

Util para manejar fechas, ya sea para despliegue o para solicitar al usuario que proporcione una fecha en específico.



Class ImageItem

Util para trabajar con archivos de imágenes en nuestra aplicación. Ya lo veremos más adelante pero con esta herramienta podremos agregarle un atractivo visual que lo haga más amigable y agradable para el usuario.


Class TextField

Util para manejar texto; que puede ser de despliegue solamente o bien, para pedir al usuario que teclee datos. Como pueden password, números, nombres, etc.



Hay que recordar que las clases gráficas de alto nivel, tienen la facilidad de que se adaptan al tipo de despliegue con que cuenta el dispositivo en el cual estamos trabajando.

En otras palabras, nosotros llamamos las clases y creamos los objetos en nuestra aplicación, pero la presentación visual queda bajo el control del hardware.



Veamos ahora, el uso de las clases que acabamos de mencionar, en un ejemplo.


import java.io.IOException;
import java.util.Date;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.DateField;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.ImageItem;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.ItemStateListener;
import javax.microedition.lcdui.TextField;
import javax.microedition.lcdui.Ticker;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;



public class MIDOtros extends MIDlet implements CommandListener, ItemStateListener {
private Ticker miMarquesina;
private DateField miFecha;
private ImageItem miImagen;
private TextField miHumor;
private Image imgSerio, imgFeliz, imgTriste;
private Command Salir;
private Display miDisplay;
private Form miForma;


public MIDOtros() {
try {
imgSerio = Image.createImage("/serio.PNG");
imgFeliz = Image.createImage("/feliz.PNG");
imgTriste = Image.createImage("/triste.PNG");
} catch (IOException e) {
e.printStackTrace();
}


Date wHoy = new Date();
miDisplay = Display.getDisplay(this);
miFecha = new DateField("Dia de hoy",DateField.DATE);
miFecha.setDate(wHoy);
miHumor = new TextField("% de Animo", "50", 2, TextField.NUMERIC);
miMarquesina = new Ticker("Ejemplo de Graficos de Alto Nivel. Tutorial para el Desarrollo de aplicaciones en móviles, País México. Noviembre del 2008");
miForma = new Form("Otros Items");
Salir = new Command("Salir", Command.EXIT, 0);
miImagen = new ImageItem(null, imgSerio, 0, null);
miForma.setTicker(miMarquesina);
miForma.append(miFecha);
miForma.append(miImagen);
miForma.append(miHumor);
miForma.addCommand(Salir);
miForma.setCommandListener(this);
miForma.setItemStateListener(this);
}


protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
}


protected void pauseApp() {
}


protected void startApp() throws MIDletStateChangeException {
this.miDisplay.setCurrent(this.miForma);
}


public void commandAction(Command arg0, Displayable arg1) {
if (arg0 == Salir){
try {
destroyApp(false);
} catch (MIDletStateChangeException e) {
e.printStackTrace();
}
notifyDestroyed();
}
}


public void itemStateChanged(Item arg0) {
if (arg0 == miHumor){
int wValor = Integer.parseInt(miHumor.getString());
if (wValor <> 70) {
miImagen.setImage(imgFeliz);
} else {
miImagen.setImage(imgSerio);
}
}
}
}
}




Como se observa, en esta aplicación manejamos archivos de imagen :


imgSerio = Image.createImage("/serio.PNG");
imgFeliz = Image.createImage("/feliz.PNG");
imgTriste = Image.createImage("/triste.PNG");




Que son archivos tipo PNG, este tipo nos permite manejar imágenes con una buena y razonable resolución y almacenarlos en poco espacio.
Bien, una vez compilado nuestro código; podemos ejecutarlo y verlo en acción.

Sunday, November 16, 2008

LAS OPCIONES DEL USUARIO

En el post anterior hablamos de la clase LIST en J2ME, pero contamos además con otra clase, CHOICEGROUP.

clase ChoiceGroup

public class ChoiceGroup extends Item implements Choice

Un componente ChoiceGroup es un grupo de elementos que podemos seleccionar. Es prácticamente lo mismo que el componente List, pero dentro de un formulario.

Para construir un objeto ChoiceGroup realizaremos una llamada a su constructor con los siguientes parámetros:

ChoiceGroup(String etiqueta, int tipo)
ChoiceGroup(String etiq, int tipo, String[] elementos, Image[] imagenes)
Y ahora veamos un ejemplo de cómo se utiliza esta clase dentro de una aplicación.

MIDChoiceGroup.java

import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.ChoiceGroup;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.ItemStateListener;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;


public class MIDChoiceGroup extends MIDlet implements CommandListener, ItemStateListener {
private Display miDisplay;
private Form miForma;
private ChoiceGroup miGrupo;
private Command Salir;

public MIDChoiceGroup() {
// TODO Auto-generated constructor stub
miDisplay = Display.getDisplay(this);
miForma = new Form("MENU PRINCIPAL");
Salir = new Command("Salir", Command.EXIT, 0);

miGrupo = new ChoiceGroup("Opciones: ", ChoiceGroup.EXCLUSIVE);
miGrupo.append("Altas", null);
miGrupo.append("Bajas", null);
miGrupo.append("Consultas", null);
miGrupo.append("Modificaciones", null);
miGrupo.append("Impresion", null);

miForma.append(miGrupo);
miForma.addCommand(Salir);
miForma.setItemStateListener(this);
miForma.setCommandListener(this);
}

protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
// TODO Auto-generated method stub

}

protected void pauseApp() {
// TODO Auto-generated method stub

}

protected void startApp() throws MIDletStateChangeException {
// TODO Auto-generated method stub
miDisplay.setCurrent(miForma);
}
public void commandAction(Command c, Displayable s) {
// TODO Auto-generated method stub
if (c == Salir){
try {
this.destroyApp(false);
notifyDestroyed();
} catch (MIDletStateChangeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

public void MuestraMensaje(){
Alert miAlerta = new Alert("Opcion", miGrupo.getString(miGrupo.getSelectedIndex()), null, null);
miDisplay.setCurrent(miAlerta, miForma);
}

public void itemStateChanged(Item i){
if (i == miGrupo){
this.MuestraMensaje();
}
}
}

Monday, November 10, 2008

EMPECEMOS POR LA PANTALLA

OPCIONES PARA EL USUARIO
Parte importante de toda interface de usuario, es que se pueda elegir la acción que se desea realizar. Ya sea por menús contextuales o barras en la parte superior o inferior de la pantalla; pero el usuario debe poder seleccionar la acción a realizar de entre un rango definido de tareas.
En el caso de J2ME se pueden utilizar las clases LIST y CHOICEGROUP; veamos una por una y un ejemplo para su uso correcto.
  • CLASE List

    public class List extends Screen implements Choice

    La clase List nos va a permitir construir pantallas que poseen una lista de opciones. Esto nos será muy útil para crear menús de manera independiente.
    La clase List implementa la interfaz Choice, para poder interactuar con las distintas opciones que se muestre en una lista (List).

Otra parte importante de toda interface gráfica, es la comunicación Aplicación-Usuario; en otras palabras, que la aplicación pueda comunicarse con el usuario en caso de ocurrir algún error, dar una advertencia o informar de algun suceso.

en J2ME se usa mucho la class Alert para encargarse de ésto.

  • CLASE Alert

    public class Alert extends Screen

    El objeto Alert representa una pantalla de aviso. Normalmente se usa cuando queremos avisar al usuario de una situación especial como, por ejemplo, un error.
    Un Alert está formado por un título, texto e imágenes si queremos. Vamos a ver como crear una pantalla de alerta. Para ello contamos con dos constructores:

    Alert(String titulo)
    Alert(String titulo, String textoalerta, Image imagen, AlertType tipo)

    Además podemos definir el tiempo que queremos que el aviso permanezca en pantalla, diferenciando de esta manera dos tipos de Alert:

    1. Modal: La pantalla de aviso permanece un tiempo indeterminado hasta que es cancelada por el usuario. Esto lo conseguimos invocando al método Alert.setTimeOut(Alert.FOREVER).

    2. No Modal: La pantalla de aviso permanece un tiempo definido por nosotros. Para ello indicaremos el tiempo en el método setTimeOut(tiempo). Una vez finalizado el tiempo, la pantalla de aviso se eliminará de pantalla y aparecerá el objeto Displayable que nosotros definamos.

    Podemos elegir el tipo de alerta que vamos a mostrar y cada tipo de alerta tiene asociado un sonido. Los tipos que podemos definir aparecen a continuación:

    ALARM Aviso de una petición previa
    CONFIRMATION Indica la aceptación de una acción
    ERROR Indica que ha ocurrido un error
    INFO Indica algún tipo de información
    WARNING Indica que puede ocurrir algún problema

Ahora veamos un ejemplo en acción:

MIDListas.java

import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.List;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;


public class MIDListas extends MIDlet implements CommandListener {
private Command salir, acepta;
private Display display;
private List miLista;
private Alert miAlerta;

public MIDListas() {

display = Display.getDisplay(this);

salir = new Command("Salir", Command.EXIT, 2);
acepta = new Command("Aceptar", Command.OK, 1);

miLista = new List("Opciones", List.IMPLICIT);
miLista.append("Altas", null);
miLista.append("Bajas", null);
miLista.append("Consultas", null);
miLista.append("Modificaciones", null);
miLista.append("Impresion", null);
miLista.addCommand(salir);

miLista.addCommand(salir);
miLista.addCommand(acepta);
miLista.setCommandListener(this);
}

protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
// TODO Auto-generated method stub
}

protected void pauseApp() {
// TODO Auto-generated method stub
}

protected void startApp() throws MIDletStateChangeException {
// TODO Auto-generated method stub
// Establecemos el "Display" actual a nuestra pantalla
display.setCurrent(miLista);
}

public void commandAction(Command c, Displayable s) {
// TODO Auto-generated method stub
if (c == this.miLista.SELECT_COMMAND){ // Si selecciono
this.MuestraMensaje();
}
if (c == salir){
try {
this.destroyApp(false);
notifyDestroyed();
} catch (MIDletStateChangeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (c == acepta){
this.MuestraMensaje();
}
}

public void MuestraMensaje(){
miAlerta = new Alert("Opcion", miLista.getString(miLista.getSelectedIndex()), null, null);
display.setCurrent(miAlerta, miLista);
}
}

Friday, November 7, 2008

INTERFAZ DE USUARIO

Interfaces Gráficas de Usuario de Alto Nivel



En esta entrega hablaremos de la interface gráfica de alto nivel, esta interfaz usa componentes tales como botones, cajas de texto, formularios, etc. Estos elementos son implementados por cada dispositivo y la finalidad de usar las APIs de alto nivel es su portabilidad. Al usar estos elementos, perdemos el control del aspecto de nuestra aplicación ya que la estética de estos componentes depende exclusivamente del dispositivo donde se ejecute. En cambio, usando estas APIs de alto nivel ganaremos un alto grado de portabilidad de la misma aplicación entre distintos dispositivos. Fundamentalmente, se usan estas APIs cuando queremos construir aplicaciones de negocios.