Cargando un archivo en nuestro editor.

0 comentarios

Hasta ahora nuestro editor de textos era lo más tonto que existía, solo tenia un entorno y lo único que se podía hacer con el era cerrarlo, vamos a mejorar un poco esto y vamos a hacer que cargue fichero, para eso en la linea que habíamos creado como menú "cargar" vamos a modificarlo y le vamos a pedir que nos cree una acción.

JMenuItem cargar = new JMenuItem(new OpenFileAction(areaTexto));

como se puede comprobar con esto estamos pasandole en lugar de un String, con lo que queremos que ponga dentro, le pasamos una acción nueva con lo que queremos que se ejecute cuando le hagamos click. A la acción ademas le tenemos que indicar que parte de nuestro frame sera el afectado, de manera que como queremos que aquello que se cargue nos lo refleje en el área de edición pues le pasamos "areaTexto" que es el que le hace referencia.

En el caso de las acciones tenemos que hacer algo especial, por las costumbres que tenemos a la hora de programar en objetos que es que cuando se hacen acciones solemos dividir las que son, digamos... habituales que serán las "BaseAction" y luego tenemos las acciones especificas de lo que queremos realizar y en algunos casos extender alguna acción contenida en la "BaseAction". Nuestro "BaseAction" quedaría de la siguiente manera.

/*
 * Fichero: BaseAction.java
 * Autor: Liem Dazkun
 * Fecha: 17/10/11
 */
package LFR.Liem.Dazkun.Test.Java.Editor.Actions;

import java.awt.event.ActionEvent;

import java.io.File;
import java.io.FileNotFoundException;

import javax.swing.AbstractAction;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.text.JTextComponent;


/**
 * Clase padre de las acciones de salvar fichero y cargar fichero con el código común
 * para ambas acciones.
.
 *
 * @author Chuidiang
 *
  */
public abstract class BaseAction extends AbstractAction
{
    /** 
     * Componente con el texto que se quiere salvar o en el que se quiere mostrar el
     * contenido del fichero.
     */
    protected JTextComponent componenteTexto;

    /** 
     * Panel que permite elegir un fichero del disco y navegar.  
     */
    private JFileChooser fileChooser = null;

    /** 
     * Si la acción va a ser para salvar o para cargar. 
     */
    private Opciones opcion;

    /** Enumerado con las posibles opciones para la acción */
    public enum Opciones
    {
     SALVAR, CARGAR;
    }

    /**
     * Crea un nuevo objeto AbstractAccionFichero.
     *
     * @param componenteTexto Componente de texto sobre el que actuar, salvando su
     * contenido o mostrando en él el contenido de un fichero.
     * @param opcion SALVAR o CARGAR.
     */
    public BaseAction(JTextComponent componenteTexto, Opciones opcion){
        this.componenteTexto = componenteTexto;
        this.opcion = opcion;
    }

    /**
     * Se ha pulsado el botón y se muestra el File Chooser.
     *
     * @param arg0 Evento de pulsación del botón.
     */
    public void actionPerformed(ActionEvent arg0)
    {
     // Se crea el FileChooser si no estaba creado.
        if (fileChooser == null)
        {
            fileChooser = new JFileChooser();
        }

        int opcionSeleccionada;

        // Se muestra el FileChooser como dialogo de salvar o de cargar según la opción
        // SALVAR o CARGAR que se haya pasado en el constructor.
        if (opcion == Opciones.SALVAR)
        {
            opcionSeleccionada = fileChooser.showSaveDialog(componenteTexto);
        }
        else
        {
            opcionSeleccionada = fileChooser.showOpenDialog(componenteTexto);
        }

        // Si el usuario elige un fichero y pulsa "OK"...
        if (JFileChooser.APPROVE_OPTION == opcionSeleccionada)
        {
         // Se obtiene el fichero
            File fichero = fileChooser.getSelectedFile();

            try
            {
             // Se salva o carga. Las clases hijas deben redefinir este método.
                actuarSobreElFichero(fichero);
            }
            catch (Exception e)
            {
             // Mensaje de error si se produce.
                JOptionPane.showMessageDialog(
                    componenteTexto, e, "Error en el fichero " + fichero,
                    JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    /**
     * Las clases hijas deben salvar el contenido del area de texto en el fichero que se
     * pasa como parámetro o leer el fichero y meter su contenido en el area de texto.
     *
     * @param fichero Fichero que se debe leer o en el que se debe grabar.
     *
     * @throws FileNotFoundException Excepción si el fichero no existe.
     */
    protected abstract void actuarSobreElFichero(File fichero)
        throws FileNotFoundException;
}



La acción para cargar el fichero quedaría de la siguiente manera.


/*
 * Fichero: OpenFileAction.java
 * Autor: Liem Dazkun
 * Fecha: 17/10/11
 */
package LFR.Liem.Dazkun.Test.Java.Editor.Actions;

import java.awt.Event;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import javax.swing.Action;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;
import javax.swing.text.JTextComponent;


/**
 * @author Liem Dazkun
 *
  */
public class OpenFileAction extends BaseAction
{
    /**
     * serial uid
     */
    private static final long serialVersionUID = 2L;

    /**
     * Crea un nuevo objeto OpenFileAction.
     *
     * @param componenteTexto Componente en el que mostrar el texto leido.
     */
    public OpenFileAction(JTextComponent componenteTexto){
     // Configurar clase padre para que sea CARGAR fichero.
        super(componenteTexto, Opciones.CARGAR);
        
        // Etiqueta y tecla aceleradora
        this.putValue(Action.NAME, "Abrir ...");
        this.putValue(Action.ACCELERATOR_KEY,KeyStroke.getAWTKeyStroke('O', Event.CTRL_MASK));
    }

    /**
     * Le el fichero que se le pasa y pone el contenido en el JTextArea.
     *
     * @param fichero Fichero a leer
     *
     * @throws FileNotFoundException No se puede abrir el fichero.
     */
    @Override
    protected void actuarSobreElFichero(File fichero)throws FileNotFoundException{
     // Se prepara el reader para leer el fichero. Un StringBuffer para compener el
     // texto total de forma eficiente, que diría rfilgueiras.
        BufferedReader reader = new BufferedReader(new FileReader(fichero));
        StringBuffer bufferTexto = new StringBuffer();

        try
        {
            String linea = reader.readLine();

            while (linea != null)
            {
             // Se va añadiendo las líneas que se leen y un separador de línea
             // adecuado para el sistema operativo. Este último puede ser /n o /r/n
             // dependiendo de si es unix o windows. System.getProperty("line.separator")
             // nos da el adecuado.
                bufferTexto.append(linea);
                bufferTexto.append(System.getProperty("line.separator"));
                
                // Siguiente linea.
                linea = reader.readLine();
            }
        }
        catch (IOException e)
        {
            JOptionPane.showMessageDialog(
                componenteTexto, e, "Error al leer fichero",
                JOptionPane.ERROR_MESSAGE);
        }

        // Se pone el texto leido en el JTextArea.
        componenteTexto.setText(bufferTexto.toString());
    }
}



Con estas dos acciones escritas podríamos ejecutar la carga de un fichero, de momento no se podría realizar nada más, pero esto seria un claro ejemplo de lo que podemos hacer con este fichero.

serialVersionUID ¿Para que sirve?

0 comentarios

Hoy me he encontrado con que no recordaba exactamente para que servia el parámetro serialVersionUID, afortunadamente no estamos en los 80 que o lo recordabas o estabas perdido. 

private static final long serialVersionUID = 1L;

Básicamente esta variable sirve para decirle a nuestro proyecto en que versión se encuentra en estos momentos y esto se debe a que todo objeto que sea susceptible a implementar un "Serializable" y se ejecute desde un entorno como Swing o Applet puede sufrir modificaciones. Pongamos que hemos creado un Applet que nos ayuda a cargar y visualizar un fichero, el programa serializara una serie de objetos al cerrarse y los lee en la siguiente ejecución para mantener los valores que tenia antes. Cuando evoluciones tu programa si no modificas el serialVersionUID e intentas leer los objetos que fueron serializados te los devolverá como erróneos, eso pasa por que los objetos locales no saben que el programa a sido modificado.

De todas maneras esta información esta extraída de: http://www.lawebdelprogramador.com creo que no necesita más presentación y de http://chuwiki.chuidiang.org que es una web que no conocía pero que esta muy bien, es más, las practicas que estoy haciendo proceden de su WIKI, la cual aconsejo leer. Se que mi descripción no es muy clara pero en todo caso en ambas paginas web se pueden encontrar sendos resultados que pueden facilita que se entiendan estas pequeñas cosas.

Fe de erratas:
Por lo visto, tal y como lo describo parece que el serialVersionUID tenga que ser el mismo que la versión del programa completo, pero no es así, el serialVersionUID  hace referencia al .class generado a partir del Java de manera que podemos tener más de un serialVersionUID en todo el programa dependiendo de que se haya modificado.

semana del año en Java

0 comentarios

En esta ocasión estamos creando el algoritmo definido por la ISO 8601 para poder poner el día de la semana en la que nos encontramos.

public class SemanaAnno{
	public Integer semanaAnno(Calendar fecha){
		//conseguimos el dia de año, un año tiene 365 dias... 366 si es bisiesto.
		Calendar cal = new GregorianCalendar();
		int mes = cal.get(fecha.MONTH)+1;
		int a = mes==1||mes==2?cal.get(fecha.YEAR)-1:cal.get(fecha.YEAR);
		int b = (a/4)-(a/100)+(a/400);
		int c = ((a-1)/4)-((a-1)/100)+((a-1)/400);
		int s = b-c;
		int e = mes==1||mes==2?0:s+1;
		int f;
		if(mes==1||mes==2){
			f=cal.get(fecha.DAY_OF_MONTH)-1+(31*(mes-1));
		}else{
			f=cal.get(fecha.DAY_OF_MONTH)+((153*(mes-3)+2)/5)+58+s;
		}
		int g = (a+b)%7;
		int d = (f+g-e)%7;
		int n = f+3-d;
		if(n<0){//Corresponde al año anterior
			return (53-((g-s)/5));
		}else if(n>364+s){//Corresponde al año siguiente
			return 1;//corresponde al año siguiente
		}else{//corresponde al año en curso.
			return (n/7)+1;
		}
	}
}

Como seguro que os lo vais a preguntar ya lo cuento de antemano, las variables no son nemotécnica por que realmente no se muy bien que es lo que estamos haciendo en cada paso, lo cual supone un gran fallo para cualquier programador, pero la verdad es que este "trabajito" ya me estaba trayendo por la calle de la amargura, no he conseguido encontrar el ISO 8601 en toda su extensión, solamente pequeñas pretensiones que indicaban el tipo de formateo permitido por la ISO, la verdad es que eso me sirvió de poco.

Las paginas que encontré con el calculo eran solamente aproximaciones que yo ya había probado, desde contar los días hasta contar el día total en el que estamos en el año, vamos lo que viene a ser el día Juliano, sumarle el día en que comenzó la semana, cosa que ya hemos calculado antes, vamos que funcionar funcionaba, pero que pasaba cuando decías de contar el 1 de Enero de cualquier año, pocas veces coincide que la semana del 1 comience en lunes, por lo que las cuentas solo salían para ciertos meses y para ejemplo un botón, el 1 de Enero del 2012 es el domingo de la semana 52 del año 2011, según nuestro recuento que pasaría,  como ha comenzado el año en domingo le sumamos cinco, se suman cinco por que la semana la iniciamos en lunes, 6/7 el mod de esta división nos daría un total de 0, se puede realizar una división normal ya que estamos dividiendo enteros y asignándoselo a enteros. Muy bien y vosotros diréis, pues ya esta si es 0 se corresponde a la ultima del año anterior, pero esto ya seria regresivo, tendríamos que volver a hacer todo pero con el 31 de Diciembre del año anterior. Pero que paso en Enero del 2009, según las cuentas hasta el día 5 no podemos marcar la primera semana del año, esto se trataría de otra excepción, por que si buscamos los calendarios de esos años nos encontraremos que la primera semana del año fue la misma que contenía el día uno.

Con el código que aquí comparto todos estos datos quedan cubiertos dando en definitiva el día exacto, igual me hacen falta más pruebas comparando con los calendarios de otros años, pero en un principio y por las pruebas realizadas este código es correcto.

El código original del que me he basado es un JavaScript que encontré en la red, lamento no poder dar referencias pero es que no me acuerdo, me lo copie en el NotePad++ y se me olvido guardar la pagina en favoritos, realmente deseo que les guste el aporte y les pueda resultar útil.

Creando un editor en Java

0 comentarios

A traves de la pagina de chuidiang he visto que daba una guia de como montar nuestro propio editor de textos con Java, en este caso es un editor muy sencillo pero que en mi caso personal me abre todo un mundo ya que estoy más acostumbrado a utilizar Java unicamente como back-end y utilizo otros frameworks para el front-end, en estos momentos para ser exactos estoy usando Flex en mi día a día.

Lo primero es generar la ventana con todos sus elementos, pero como eso nos dejaria una función principal demasiado pesada lo que tenemos que hacer es generar un constructor que divida los problemas para que los separe y los trate de manera personal.
Y por eso nuestro constructor quedaria de la siguiente manera

    public LDEditor()
    {
        JMenuBar barraMenu = new JMenuBar();
        
        areaTexto = new JTextArea(30, 90);
        
        buildFileMenu(barraMenu);
        buildEditMenu(barraMenu);

        JFrame frame = buildEditorWindow(barraMenu);
        viewWindow(frame);
    }

JTextArea solicita dos parametros de tipo integer para poder definir cuanto tiene que medir, en mi caso quiero que se visualicen treinta lineas y noventa columnas "JTextArea(int rows, int columns)"

Ahora generaremos todo el codigo para crear el menu correspondiente a "Archivo".
En este menu incluiremos las tres opciones basicas: Salvar, cargar y Salir.

Para ello creamos los tres items del menu, despues creamos el menu propiamente dicho y le añadiremos los tres items.
Tras esto añadimos todo el menu a la barra de menu que hemos recibido por parametro.

    private void buildFileMenu(JMenuBar barraMenu)
    {
        JMenuItem salvar = new JMenuItem("Salvar");
        JMenuItem cargar = new JMenuItem("Cargar");
        JMenuItem salir = new JMenuItem("Salir");
        
        JMenu menuArchivo = new JMenu("Archivo");
        
        menuArchivo.add(salvar);
        menuArchivo.add(cargar);
        menuArchivo.add(salir);
        
        barraMenu.add(menuArchivo);
    }

Ahora haremos el mismo proceso para el menu de edicion.
En este caso hay una modificación, y es que para separar la opcion de buscar y de las que editan el texto hemos metido un separador, para ello se ha introducido " menuEditar.add(new JSeparator());" se añade como un item más y ya que no vamos a hacer nada más con él no hace falta crearlo como variable

    private void buildEditMenu(JMenuBar barraMenu)
    {
        JMenuItem buscar = new JMenuItem("Buscar");
        JMenuItem copiar = new JMenuItem("Copiar");
        JMenuItem cortar = new JMenuItem("Cortar");
        JMenuItem pegar  = new JMenuItem("Pegar");

        JMenu menuEditar = new JMenu("Editar");
        menuEditar.add(buscar);
        
        menuEditar.add(new JSeparator());
		
        menuEditar.add(cortar);
        menuEditar.add(copiar);
        menuEditar.add(pegar);
        
        barraMenu.add(menuEditar);
    }

Ahora vamos a juntar todo para crear un JFrame

    private JFrame buildEditorWindow(JMenuBar barraMenu)
    {
        JFrame frame = new JFrame("Test de editor de Liem Dazkun");
        
        //El menú va en la parte superior,
        frame.getContentPane().add(barraMenu, BorderLayout.NORTH);
        
        //El comando que activa / desactiva el ajuste de linea 
        areaTexto.setLineWrap(true);
        
        //El comando que hace que el ajuste de linea se haga donde haya un espacion en blanco.
        areaTexto.setWrapStyleWord(true);

        JScrollPane scroll = new JScrollPane(areaTexto);
        
        // El scroll con el JTextArea se añade por defecto en el centro del BorderLayout.
        frame.getContentPane().add(scroll);

        return frame;
    }

Finalmente cargamos y lanzamos toda la pantalla para que se pueda visualizar.

    private void viewWindow(JFrame frame)
    {
    	// Para salir del programa en caso de pulsar el aspa de la esquina superior derecha de la ventana.
    	frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        
        // La ventana coge el tamaño justo para que se vean completamente todos los componentes
    	frame.pack();

        // Se obtienen las dimensiones en pixels de la pantalla.
        Dimension pantalla = Toolkit.getDefaultToolkit().getScreenSize();
        
        // Se obtienen las dimensiones en pixels de la ventana.
        Dimension ventana = frame.getSize();
        
        // Una cuenta para situar la ventana en el centro de la pantalla.
        frame.setLocation(
            (pantalla.width - ventana.width) / 2,
            (pantalla.height - ventana.height) / 2);
        
        // Se visualiza la ventana.
        frame.setVisible(true);
    }

¿En que día de la semana vivimos? escrito en Java

0 comentarios


Basándome en los datos extraídos de la Wikipedia  he confeccionado la función necesaria para saber si nos encontramos a martes o a miércoles.

Lo primero que se tiene que hacer es cargar unas contantes, la primera fila corresponde a los días de la semana, se coloca como primer día el domingo por que es el séptimo día de la semana y lógicamente cuando se calcula el resto dividiendolo entre siete da cero.
La segunda fila es un array de arrays de integer, estos campos son calculables, pero son unos datos constantes de manera que no los meto en la función por la carga de proceso, que no seria muy grande, pero si el código lo llevamos a un proyecto más grande este se puede resentir por tanto calculo. De todos modos el calculo es muy sencillo, es el modulo de la suma de los módulos del máximo de días de los meses, o lo que es lo mismo si hablamos de marzo seria (31%7 + 28%7 + 31%7)%7, en año bisiesto seria (31%7 + 29%7 + 31%7)%7, siempre es lo mismo por eso no vale la pena y lo cargo en un método estático.

//Se cargan los datos que seran constantes durante todo el proceso.
public static final String[] diaSemana = {"Domingo", "Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado"};
public static final int[][]modulos = {{0,3,3,6,1,4,6,2,5,0,3,5},{0,3,4,0,2,5,0,3,6,1,4,6}};

Despues el metodo que hace falta para hacer el caculo seria:

public int calculoDia(Calendar fecha){
	//Generamos las variables necesarias
	AnnoBisiesto annoBisiesto = new AnnoBisiesto();//La clase que nos calculara si el año es bisiesto o no.
	Calendar c = new GregorianCalendar();//necesario para convertir los datos a fecha actual
	int diaSemana; //sera el dia que devolvemos 0 = Domingo
	int mM; // es el modulo del mes, es un dato calculable pero al ser constante lo pongo como estatico.
	int year = c.get(fecha.YEAR);//El año
	int dia = c.get(fecha.DAY_OF_MONTH);//El dia al que estamos
	int sum1, sum2, sum3, temp1, temp2, temp3;//creamos tres de las cuatro sumas. Los temporales hacen falta ya que no se cuenta el resto de las divisiones
	//miramos si el año es bisiesto para asignar 0 o 1, necesario para la seleccion del array
	int bisiesto = annoBisiesto.AnnoBisiestoGood(fecha)?1:0;
	//extraemos el modulo que se utilizara para la suma total
	mM = modulos[bisiesto][c.get(fecha.MONTH)];
	//El tratamiento son cuatro sumas de cuatro modulos de 7
	//la formula seria
	//((A-1)%7+((A-1/4)-(3*((A-1/100)+1)/4))%7+DM%7+D%7)%7
	//donde A=año, DM=Dias transcurridos hasta antes del primer dia del mes, D=dia, % = Modulo y en todas las divisiones solo se consideran las cifras enteras.
	sum1 = (year-1)%7;
	temp1 = (year - 1)/4;
	temp2 = (year - 1)/100;
	temp3 = ((temp2+1)*3)/4;
	sum2 = (temp1 - temp3)%7;
	sum3 = dia%7;
	diaSemana = (sum1 + sum2 + mM + sum3)%7;
	return diaSemana;
}

Recordemos que la división de dos enteros da como resultado un long, por eso utilizo los temporales, para que se eliminen los restos y trabaje solamente con enteros tras una división. Recordemos también que la función "annoBisiesto.AnnoBisiestoGood" esta escrita en la anterior publicación de este blog, por si alguno no sabe como calcular el año bisiesto.

Y con este código tenemos el calculo completo de en que día vivimos.

Año bisiesto en Java

0 comentarios


Hay un problema muy simple de solucionar que es prácticamente uno de los primeros que se pide cuando estas estudiando programación, la gente normal, entre la que me incluyo, suele hacerlo paso a paso dando como resultado el "AnnoBisiestoBad" el cual es correcto al 100%, no nos engañemos, pero como se puede observar en "AnnoBisiestoGood" es que no es para nada optimo ya que con una sola linea podríamos haber resuelto el problema.


package LFR.Liem.Dazkun.Test.Java.Fecha.AnnoBisiesto;

import java.util.Calendar;

public class AnnoBisiesto{
	public boolean AnnoBisiestoBad(Calendar fecha){
	{
		int anno = fecha.YEAR;
	   //Si el año es divisible por 4, puede ser bisiesto
	   if (anno % 4 == 0){
	      if ((anno % 100 == 0) &&  //Si es divisible por 100
	           (anno % 400 != 0)){    //y no por 400
	             return false; //entonces no es bisiesto
	         }else{
	            return true; //En caso contrario sí lo es.
	         }
	      }else {//Si el año no es divisible entre 4 no es bisiesto.
	         return false;
	      }
		}
	}
	public boolean AnnoBisiestoGood(Calendar fecha){
		return (fecha.YEAR % 4 == 0) && !(fecha.YEAR % 100 == 0 && fecha.YEAR % 400 != 0);
	}
}


Esta es una parte del problema que intentare tener terminado a lo largo de la semana. La otra semana un compañero me planteo un problema que en un principio parece sencillo y es saber si estamos a lunes o a martes, algunos me dirán que eso ya lo hace de manera automática las librerías, pero que pasa si lo que quieres es extrapolarlo a otros entornos que no disponen de estas librerías, ¿alguno sabría hacerlo?, por eso me lo he planteado.

El problema de los test mal planificados.

0 comentarios

Muy a menudo en nuestro día a día podemos encontrarnos que el trabajo no esta del todo bien planificado, pero lo normal es conseguir sacar el trabajo y seguir para adelante sin mirar atrás. Ese no es mi caso, me encuentro en un proyecto con una gran envergadura en el que estamos involucrados más de 300 personas, donde el caos reina en cada esquina y en cada linea de codigo, tanto es así que en estos momentos estoy realizando las pruebas unitarías usando una herramienta denominada JUnit de la cual en otro momento explicare alguna cosa.
El problema en este caso es que estos test se estan efectuando sobre los servicios, los cuáles son un nodo de interconexión entre la BBDD y el código Java. A estas alturas del proyecto los servicios deberían ser definitivos y no tocarse, la realidad es muy diferente, los servicios estan en continua evolucion hasta el punto de pasar de un solo @autowired a cinco lo que nos lleva a pasar de dos pruebas a un mínimo de diez.Lo peor de este tema es que los jefes han olvidado que sucede en este tipo de tarea cuando todavía esta viva y es que el resultado que puedes esperar como mucho es de mantenimiento, siempre habrá un servicio que sera modificado y eso es lo que me duele, que siendo yo el unico  que realiza esta tarea de mi grupo se me señale con el dedo y me digan que no hay resultados.Por poner un ejemplo, el viernes cuando me fui deje el modulo al 74% , hoy nada más comenzar el día he sincronizado todo el proyecto y ese modulo se encontrarba al 40%. Falta matizar que siempre sincronizo antes de subir nada, me encanta asegurarme de que lo que subo no fastidia a nadie.La solución para este tipo de problemas es fácil, se puede realizar de dos maneras; una sería el posponer la realización de los mismos, pero como esto no puede ser pasamos a la segunda que sería tan básica como que cada programador se ocupara siempre de su test, de esta manera nos ahorraríamos sorpresas inesperadas como la que he tenido esta mañana, todos aprenderíamos y los test se realizarían mucho más exacto.

Buscador de iconos

0 comentarios



Hoy he podido encontrar un servicio de buscador de iconos, cierto es que google te permite buscar también iconos pero en el caso de este buscador sabes que todos son gratuitos, incluso dispone de un desplegable con el que se puede ver toda la codificación del archivo incluida la licencia bajo la que trabaja.

La búsqueda se puede filtrar por tamaño, por licencia y lógicamente por nombre, dispone de la opción de modificar el background de las imágenes para poder ver si son o no transparente.

Lo mejor es que cuando has encontrado el icono que querías al seguir el link te da no solo el tamaño que habías solicitado si no que te muestra en cuantos tamaños más lo tiene.

Todo un hallazgo que vale la pena visitar como mínimo una vez http://www.iconfinder.com.

Uso de fechas con Oracle

0 comentarios

Me doy cuenta de que hace mucho que no escribo nada por aquí. De igual manera he visto que no doy nunca un monográfico sobre algo.
Bueno, todo eso cambia hoy, mi primer monográfico es sobre el uso de las fechas dentro de Oracle

Lo primero que se tiene que conocer son los rangos máximos por lo que se puede mover uno, el tramo por el que nos podemos mover es el comprendido entre el -4713 AC hasta el 9999DC

Una manera muy sencilla de conseguir extraer la fecha seria con el comando:

SELECT sysdate FROM dual;

Con el uso de la función ADD_MONTHS podemos añadir o quitar meses a una fecha dada.

SELECT ADD_MONTHS(sysdate,1) FROM dual;

La función ADD_MONTHS contiene dos parámetros, el primero hace referencia a una fecha dada, en mi caso uso sysdate pero se puede usar cualquier cosa. El segundo parámetro es el que nos definirá cuantos meses se avanzan o retroceden.

Con el uso de la función LAST_DAY podemos averiguar cual seria el ultimo día del mes que le pasemos como parámetro

SELECT LAST_DAY(sysdate) FROM dual;

Con la función NEXT_DAY podemos averiguar que día sera el próximo domingo o en que cayo el siguiente domingo de una fecha dada.

SELECT NEXT_DAY(sysdate,'domingo') FROM dual;

En este caso siempre me ha surgido una duda, por que la búsqueda depende muchísimo del entorno en el que se ejecuta, por que vamos que 'Sunday' es lo mismo en concepto que 'domingo' pero no se escribe igual y la búsqueda se esta haciendo con un string. Motivo por el que no recomiendo el uso de esta característica si no se esta seguro que la base de datos siempre va a estar en un mismo idioma o en caso contrario se pueda tener este string lo suficientemente controlado como para que se cambie inmediatamente

Con la función MONTHS_BETWEEN podemos comprobar los meses que transcurren entre dos fechas determinadas.

SELECT months_between('3/06/08','5/01/09') FROM dual;

En este caso tenemos que tener cuidado de que la primera fecha sea siempre inferior a la segunda

Con la función TRUNC nos dirá el primer día correspondiente a lo que le pasemos en el segundo parámetro

SELECT trunc(sysdate,'year') FROM dual;

Con el mes, devolvería el primer día del mes y con el día el primer día de la semana

Con la función ROUND nos redondeara las fechas de igual manera que lo puede hacer con los numeros.

SELECT round(sysdate,'year') FROM dual;

Con la función CURRENT_DATE podremos observar la fecha actual.

SELECT CURRENT_DATE FROM dual;

Con la función SYSTIMESTAMP podremos observar la fecha actual, seria igual que la anterior función pero en este caso nos devuelve todos los datos.

SELECT SYSTIMESTAMP FROM dual;

Devuelve todo el formato de la fecha (20/06/11 12:41:33,296000 +01:00)

Con la función EXTRACT podremos extraer un dato de la fecha

SELECT extract(year FROM date '1998-03-07') FROM dual;

Podemos sustituir year por month o day.
También podemos obtener horas, minutos o segundos de la misma forma

SELECT extract(hour FROM time '06:07:04') FROM dual;

Gestion de errores en JQuery

0 comentarios

Un error que me he encontrado haciendo un pequeño desarrollo, este desarrollo comenzaba en una pagina HTML y derivaba hacia un servlet de Java, si tenemos en cuenta que el servicio java tiene unos time outs configurados y que este servlet tiene una integración con tres bases de datos tenemos que no se podía controlar íntegramente por el time out.

Por ese motivo se creo un sistema de errores para mostrar un mensaje de time out.


$.ajax({
data: params,
type: "POST",
url: action,
timeout: 30000,//Aquí le indicamos cuanto tardara en saltar el error en este caso 30 seg.
contentType: "application/x-www-form-urlencoded;charset=UTF-8",
dataType: 'xml',
success: 
function(xml){
   $('input, select').removeAttr('disabled');
    $('a').css('color', 'red');
    
   $('p:first').html(
    $('#messages p#respuesta_'+$('respuesta',xml).text()).html()
   );
   $('form.clicktocall, input.volver').css('display', 'none');
   if($('#messages p#respuesta_'+$('respuesta',xml).text()).attr('class')=="ms")
    $('input.volver').css('display', 'inline'); 
   $('.clicktocall_form').fadeTo('slow',1);
   $('.thickbox-clicktocall').attr('class', 'thickbox-clicktocall thickbox-clicktocall-respuesta');
   $('.clicktocall-respuesta').fadeIn('slow');
 },
 error: //Pasados los 30 seg. saltaria este error
  function( objAJAXRequest, strError ){
   $('input, select').removeAttr('disabled');
    $('a').css('color', 'red');
    
   $('p:first').html($('#messages p#respuesta_error'));
   $('form.clicktocall, input.volver').css('display', 'none');
    $('input.volver').css('display', 'inline'); 
   $('.clicktocall_form').fadeTo('slow',1);
   $('.thickbox-clicktocall').attr('class', 'thickbox-clicktocall thickbox-clicktocall-respuesta');
   $('.clicktocall-respuesta').fadeIn('slow');
 
  }
});

Lógicamente aquí veis que faltan los datos que se muestran en cada momento, pero lo que nos interesa es el tratamiento del error, aunque parezca raro dentro de la parte de error tenemos una función "function( objAJAXRequest, strError )" que es necesario que lleve estos dos parámetros, hice pruebas con diferentes parámetros, pero el resultado no fue el deseado.