Archivo de la categoría "Espai Formación"

Multiproyecto en Maven2

Jueves, 7 de Agosto de 2008

Estos dias he tenido un pequeño problema, y es que he tenido que crear un multiproyecto en maven 2, pero no sabía a priori como hacerlo. Sabía la teoría… Un directorio de proyecto “Padre”, el cual tiene un pom.xml en el cual hace referencia a los proyectos que lo forman. Y luego, varios directorios de proyectos “Hijo” dentro de “Padre” los cuales son proyectos (llamémosles) normales de maven.

El problema, es que la teoría me la sabía pero en la práctica no encontré ningún sitio que dijeran específicamente cómo se creaba un multiproyecto de maven. No sabía si tendría que hacer algo del estilo: mvn archetype:create -DarchetypeArtifactId=maven-multiproject o qué…

Al final la solución…mucho más sencilla que todo eso y os la relato a continuación.

1.- Crear “a mano” el directorio padre.

2.- Crear los proyectos que lo compondrán dentro del directorio padre. Éstos los crearemos con mvn archetype:create…

3.- Poner el siguiente archivo pom.xml dentro del directorio padre et voilá! ya tenemos nuestro multiproyecto.

A partir de ahí simplemente hacer mvn install, mvn package o lo que queramos desde el directorio del padre.

<project xmlns=”http://maven.apache.org/POM/4.0.0″
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd”>
<modelVersion>4.0.0</modelVersion>
<groupId>com.etconsultors.padre</groupId>
<version>1.0</version>
<artifactId>padre</artifactId>
<packaging>pom</packaging>
<modules>
<module>hijo1</module>
<module>hijo2</module>
<module>hijo3</module>
</modules>
</project>

Simplemente comentar que se pueden poner tantos modules como se quieran y que el orden importa, es decir, si hijo2 depende de que se cree el jar de hijo1 pues obviamente deberemos ponerlo en el orden correcto. Sobra decir que cada module deberá ser un proyecto maven2 correcto con su pom.xml y todo.

Con esto me despido y pronto os iré poniendo nuevas entregas de maven, que últimamente estoy entretenido con él.

Internet Explorer y CSS

Miércoles, 23 de Julio de 2008

Este post va dedicado a todas aquellas personas que, como yo, hemos realizado webs y nos hemos tenido que pegar (a veces literalmente) cabezazos contra la pared porque en IE, al no regirse por los standares,  no se ve la web igual que con otros navegadores. ¡Con lo rebonica que se ve en FIREFOX!

Pues bien, para todos los que sufrimos y, a la vez, no tenemos más remedio que soportar la desidia de cambiar código para que en Internet Explorer el diseño de la web no varíe demasiado, voy a mostraros algún truco en CSS para programar sólo para él.

Es posible que muchos lo conozcais y también es posible que para otros sea algo nuevo que puede aportar grandes cosas a su desarrollo, se trata de los “Hacks”. Esta solución la propuso Edwardson Tan y consiste en hacer que sólo Internet Explorer interprete ciertas instrucciones CSS. Hay varias formas de realizar esto:

1) Para que lo lean todos los exploradores salvo Internet Explorer:

#miCapa {

margin-top: 5px;

}

html>body #miCapa {

margin-top: 1px;

}

Internet Explorer no interpreta “html>body” mientras que el resto de navegadores sí, por lo que el último   bloque será el que aplicará Firefox, Opera, etc.

2) Para que sólo lo lea Internet Exporer:

#miCapa {

margin-top: 1px;

*margin-top: 5px;

}

Sólo Internet Explorer sabrá que tiene que utilizar un margen superior de 5px.

Rizando el rizo, también podemos diferenciar entre IE6 e IE7 ya que tampoco funcionan de la misma manera:

#miCapa {

margin-top: 1px;

*margin-top: 5px;   //IE 7

_margin-top: 7px;   //IE6

}

Internet Explorer 6 es el único que procesa correctamente el guión bajo “_”, también se podría utilizar una barra invertida de esta manera “mar\gin-top: 7px” . IE5 e IE6 son los únicos que son capaces de escapar la barra invertida dentro del nombre de una propiedad en un CSS.

Como crear un TreeComboBox en Gwt-Ext

Miércoles, 2 de Julio de 2008

Hace un tiempo me encontré con la necesidad de crear un ComboBox en Gwt-Ext que dentro pudiera tener muchos resultados mostrados en forma de árbol, lo que, en un alarde de originalidad, he llamado “TreeComboBox”.

La forma de crearlo es fácil, aunque hay que darle un par de vueltas para conseguir el resultado que deseamos. Lo primero que debemos hacer es crear el ComboBox donde queremos visualizar el árbol:

ComboBox cb = new ComboBox();

cb.setEditable(false);
cb.setMinChars(0);
cb.setMode(ComboBox.LOCAL);
cb.setStore(new SimpleStore(”", new Object[] {”"}));
cb.setListAlign(”tl-bl”);
cb.setListWidth(250);
cb.setTpl(”<tpl for=’.'><div style=’height:200px’><div id=’”+cb.getId()+”‘></div></div></tpl>”);

Como podemos ver, creamos un ComboBox normalmente, cabe resaltar varias cosas:

  • STORE: El Store se crea vacío ya que el Combo se va a nutrir del árbol.
  • LISTALIGN y LISTWIDTH: Valores para el desplegable, se alinea a la izquierda y abajo con un ancho de 250px.
  • TPL: Quizá el más importante, este template podeis copiarlo tal cual, pero la parte más importante es el ID del div (<div id=’”+cb.getId()+”‘>) porque es el identificador que utilizaremos para renderizar el árbol.

Posteriormente se ha de crear el árbol (para ver ejemplos visitar las demos de Gwt-ext) al que llamaremos INSIDETREE para tener la referencia.

Una vez realizados estos pasos veremos la forma de mantenerlos linkados:

cb.addListener(new ComboBoxListenerAdapter() {
public void onExpand(ComboBox comboBox) { insideTree.render(comboBox.getId()); }
});

Con este código conseguimos que, cuando se expanda el combo, se renderice el árbol dentro (”insideTree.render(comboBox.getId());”), fácil, ¿no?

Para tener un control sobre lo seleccionado en el árbol se debe añadir el siguiente código. Además con el click en el árbol podemos lanzar en el evento select del Combo en el caso de que lo necesitemos para que funcione como un ComboBox normal.

insideTree.addListener(new TreePanelListenerAdapter() {
public void onClick(TreeNode node, EventObject e) {
if(node.isLeaf()) {

//HACER LO NECESARIO CON LOS DATOS
collapse(); //CERRAMOS LA LISTA
fireEvent(”select”); // LANZAMOS EL EVENTO SELECT (Si se requiere)
}
}
});

Mootools horizontal accordion

Jueves, 26 de Junio de 2008

Aquellos que hayan visitado nuestra web (y los que no, podéis hacerlo ahora), habrán visto la animación que hay en la pantalla principal. Consiste en una animación con Fx.Elements la cual, al hacer clic en alguna de las secciones, se convierte en un acordeón horizontal. Ambos efectos han sido realizados con la librería javascript mootools 1.1.

Voy a ahorrarme la parte de hacer la animación Fx.Elements porque es trivial y sólo con ver la demo en la web oficial de mootools se consigue, aún así si teneis cualquier duda… os será resuelta e incluso puedo colgar el ejemplo de como hacerlo.

La realización del acordeón consta de tres partes, que vamos a diferenciar.

HTML:

<div id=”servicios”>
<h5 id=”h5eprs”></h5>

<div id=”eprs” class=”servicio”>Texto a mostrar en primera sección</div>

<h5 id=”h5eprd”></h5>
<div id=”eprd” class=”servicio”>Texto a mostrar en segunda sección</div>

<h5 id=”h5efrm”></h5>
<div id=”efrm” class=”servicio”>Texto a mostrar en tercera sección</div>
</div>

Tenemos una capa “servicios” que será el contenedor de todas las partes del acordeón, cada parte del acordeón está formada por una cabecera, y un cuerpo. La cabecera puede ser un div, span… en nuestro caso es un h5, el cuerpo será un div.

Como podemos apreciar en el ejemplo tenemos tres partes de acordeón; tres cabeceras (h5) y tres cuerpos (div).

CSS:

#h5eprs {
background-image: url(barra_eprs.png);
}

#h5eprd {
background-image: url(barra_eprd.png);
}

#h5efrm {
background-image: url(barra_efrm.png);
}
#servicios {
position: relative;
float:left;
}

#servicios .servicio {
float: left;
position: relative;
display: block;
width: 160px;
height: 336px;
background-repeat:no-repeat;
background-position: 25px 49%;
margin-top: -1px;
}

#eprs { background-image:url(e_eprs.png); border-right: 1px solid black;}
#eprd { background-image:url(e_eprd.png); border-right: 1px solid black;}
#efrm { background-image:url(e_efrm.png); }

El CSS en este caso no tiene gran poder para el acordeón, pero indica el posicionamiento del acordeón (#servicios), y el estilo que deseamos que tenga, tanto las partes plegadas (h5), como los contenidos (#servicios .servicio e ids de cada uno) que en este caso sólo muestran imágenes de fondo.

JS:

accordion = new Accordion(’#servicios h5′, ‘#servicios div’,
{
width: true,
fixedWidth: 390, /* Colocamos el ancho y el alto total del acordeón */
fixedHeight: 335,
display: index;
});

En este apartado, lo único reseñable es el atributo WIDTH, éste es el que determinará si el acordeón es horizontal. Los otros parámetros definen el ancho y el alto total del acordeón (el FIXEDWIDTH sólo funciona en acordeones horizontales), el parámetro INDEX indica que sección dentro del acordeón queremos mostrar cuando se visualice, en nuestro caso le pasamos el valor de la sección en la que se ha clicado, pero puede ponerse un valor fijo.

Recordad que el código JS hay que introducirlo dentro de:

window.addEvent(’domready’, function() {

//COLOCAR EL CÓDIGO DEL ACORDEÓN AQUÍ

});

Es un ejemplo fácil y sencillo, aunque crear un acordeón con mootools no es muy complicado aquí os dejo este pequeño tutorial.

El patrón Abstract Factory (Factoría abstracta)

Martes, 3 de Junio de 2008

Como he comentado en otro post, ultimamente estamos trabajando en el proyecto OrbisGIS. El cual es un GIS libre y … bla bla bla… Esto ya lo dijimos, así que no lo vamos a repetir.

El caso es que la parte que estamos desarrollando tiene una cosa interesante, y es que ha de ser extensible…Haaaay, la extensibilidad…que gran amigo y enemigo de los desarrolladores si lo queremos hacer bien. El caso es que para esto, como para casi todo, hay cosas inventadas. Y la cosa inventada para este caso es un patrón de diseño llamado Fábrica Abstracta (aka. Abstract Factory).

En este post os voy a comentar un poco como se usaría y os voy a poner un ejemplo que no tiene funcionalidad ninguna, pero que os puede servir de guia.

La fábrica abstracta soluciona el problema de crear diferentes familias de objetos. Por ejemplo, en nuestro caso estamos desarrollando un panel de leyendas, el cual tendrá diferentes tipos de leyendas, pero todas tienen que tener muchas cosas en común. Para esto creamos dos clases abstractas. Una fábrica abstracta y una leyenda abstracta y luego, de cada leyenda concreta creamos una fabrica concreta. Veamos el código:

//abstract factory
abstract class CUIFactory{
    public static CUIFactory getFactory(int clasif){
        switch (clasif){
            case GeometryClasification.UNIQUE_SYMBOL:
                return new UniqueSymbolFactory();
            case GeometryClassification.UNIQUE_VALUE:
                return new UniqueValueFactory();
            default:
                return new NullFactory();
        }
    }
    public abstract JCUIPane createPanel();
}

//concrete factory 1
class UniqueSymbolFactory extends CUIFactory{
    public JCUIPane createPanel(){
        return new JUniqueSymbolPanel();
    }
}

//concrete factory 2
class UniqueValueFactory extends CUIFactory{
    public JCUIPane createPanel(){
        return new JUniqueValuePanel();
    }
}

//concrete factory 3
class NullFactory extends CUIFactory{
    public JCUIPane createPanel(){
        return new JNullPanel();
    }
}

//abstract panel
abstract class JCUIPane extends JPanel{
    public abstract void initComponents();
}

//concrete panel 1
class JUniqueSymbolPanel extends JCUIPane{
    public void initComponents(){ //initialize unique symbol components };
}

//concrete panel 2
class JUniqueValuePanel extends JCUIPane{
    public void initComponents(){ //initialize unique value components };
}

//concrete panel 3
class JNullPanel extends JCUIPane{
    public void initComponents(){ //initialize null components };
}

//example using the abstract factory
public class Application{
    public static void main(String [] args){
//args has the type of the geometry that we want to create
        CUIFactory factory = CUIFactory.getFactory(Integer.parseInt(args[0]));
        JCUIPane panel = factory.createPanel();
        JFrame frame = new JFrame();
        frame.add(panel);
        frame.setVisible(true);
    }
}

Cerrar
Enviar por Correo