Noticias Weblogs Foros Wiki Código
Sponsors:

Meta-Info

¿Que es?

Planeta Código es un agregador de weblogs sobre programación y desarrollo en castellano. Si eres lector te permite seguirlos de modo cómodo en esta misma página o mediante el fichero de subscripción.

rss subscripción

Sponsors

Anunciarse aquí

PlanetaCódigo en inglés

Puedes utilizar las siguientes imagenes para enlazar PlanetaCodigo:
planetacodigo

planetacodigo

Si tienes un weblog de programación y quieres ser añadido aquí, envíame un email solicitándolo.

Idea: Juanjo Navarro

Diseño: Albin

código escrito

Puntos de salida y estilo de programación

Noviembre 29th, 2004 - [Enlace local]

Hace unos días, cuando nuestro profesor de programación nos explicó los bucles en Pascal, me extrañó bastante que no nombrara alguna sentencia que rompiera la secuencia de un while para forzar la salida del bucle en un momento determinado. Al...

» Leer más, comentarios, etc...

El arte de programar

Transparencias con Windows y GDI en Visual Basic

Noviembre 29th, 2004 - [Enlace local]

En el trabajo me surgió la problematica de hacer que una imágen tenga un grado de transparencia sobre otra. Esto, aunque parezca una trivialidad, no lo es puesto que aunque la solución original es generar una mascara para hacer la transparencia, el permitir que existan varios grados lo complica un poco. Sin embargo al final he conseguido compactarlo todo en un procedimiento para que pasandole como parametros el dispositivo de contexto de origen, el dispositivo de contexto de destino (y donde se almacenará el resultado de la transparencia), las dimensiones de la imagen (en mi caso suelo poner las dimensiones en pixeles del picturebox) y el grado porcentual de transparencia, se genera de un modo casi inmediato el efecto deseado. Aqui os dejo el código:

' AUTOR: Oscar Rodríguez
' NOMBRE: Transparenta
' FUNCIONAMINETO: Esta función permite fusionar una imágen de frente con otra de fondo
' dado un grado de transparencia
' PARÃ?METROS:
' -OrigenDC: Dispositivo de Contexto de la imágen de frente
' -DestinoDC: Dispositivo de Contexto de la imágen de fondo y resultado de la operación
' -Anchura: Anchura de las imágenes
' -Altura: Altura de las imágenes
' -Transparencia: Grado de transparencia medida en %
Public Sub Transparenta(ByVal OrigenDC As Long, ByVal DestinoDC As Long, ByVal Anchura As Long, ByVal Altura As Long, ByVal Transparencia As Byte)
Dim bitmap_info As BITMAPINFO
Dim indice As Long, tamano As Long
Dim pixels() As Byte
Dim TemporalDC As Long, TemporalDC2 As Long, MascaraDC As Long
Dim BitMap As Long, AntiguoBitMap As Long, BitMap2 As Long
Dim AntiguoBitMap2 As Long, MascaraBitMap As Long, AntiguoMascaraBitMap As Long
Dim recta As RECT
Dim brocha As Long

' Creamos el DC y bitmap de la mascara
MascaraDC = CreateCompatibleDC(OrigenDC)
MascaraBitMap = CreateCompatibleBitmap(OrigenDC, Anchura, Altura)
AntiguoMascaraBitMap = SelectObject(MascaraDC, MascaraBitMap)
' Copiamos la imágen de frente a la mascara
BitBlt MascaraDC, 0, 0, Anchura, Altura, OrigenDC, 0, 0, SRCCOPY

' Establecemos las propiedades de la cabecera bitmap
With bitmap_info.bmiHeader
.biSize = 40
.biWidth = Anchura
.biHeight = Altura
.biPlanes = 1
.biBitCount = 32
.biCompression = BI_RGB
End With
' Creamos el buffer donde almacenaremos los bytes de la imágen de la mascara
tamano = 4 * Anchura * Altura
ReDim pixels(tamano) As Byte
' Guardamos en el buffer los bytes de la imágen de la mascara
GetDIBits MascaraDC, MascaraBitMap, _
0, Altura, pixels(0), _
bitmap_info, DIB_RGB_COLORS

' Calculamos la transparencia según el % que nos han pasado
Transparencia = Transparencia * 255 / 100
' Recorremos todo el buffer para sustituir los colores distintos de blanco por
' el de la transparencia
For indice = 0 To tamano - 1 Step 4
If pixels(indice) <> 255 Or pixels(indice + 1) <> 255 Or pixels(indice + 2) <> 255 Then
pixels(indice) = Transparencia
pixels(indice + 1) = Transparencia
pixels(indice + 2) = Transparencia
End If
Next

' Copiamos los bytes modifcados del buffer de nuevo a la imágen de la mascara
SetDIBits MascaraDC, MascaraBitMap, _
0, Altura, pixels(0), _
bitmap_info, DIB_RGB_COLORS

' Establecemos los valores del rectangulo para que coincida con las dimensiones
' de las imágenes
recta.Top = 0
recta.Left = 0
recta.Right = Anchura
recta.Bottom = Altura

' Creamos una brocha blanca para pintar los DC temporales con ese color
brocha = CreateSolidBrush(&HFFFFFF)

' Creamos el DC y bitmap de la imágen temporal nº1
TemporalDC = CreateCompatibleDC(OrigenDC)
BitMap = CreateCompatibleBitmap(OrigenDC, Anchura, Altura)
AntiguoBitMap = SelectObject(TemporalDC, BitMap)
' Pintamos de blanco la imágen temporal nº1
FillRect TemporalDC, recta, brocha
' Copiamos la imágen de la mascara invertida en colores a la imágen temporal nº1
BitBlt TemporalDC, 0, 0, Anchura, Altura, MascaraDC, 0, 0, SRCINVERT
' Mezclamos la imágen de frente con la imágen temporal nº1
BitBlt TemporalDC, 0, 0, Anchura, Altura, OrigenDC, 0, 0, SRCAND


' Creamos el DC y bitmap de la imágen temporal nº2 y lo pintamos de blanco
TemporalDC2 = CreateCompatibleDC(DestinoDC)
BitMap2 = CreateCompatibleBitmap(DestinoDC, Anchura, Altura)
AntiguoBitMap2 = SelectObject(TemporalDC2, BitMap2)
' Pintamos de blanco la imágen temporal nº2
FillRect TemporalDC2, recta, brocha
' Copiamos la imágen de la mascara a la imágen temporal nº2
BitBlt TemporalDC2, 0, 0, Anchura, Altura, MascaraDC, 0, 0, SRCCOPY
' Mezclamos la imágen de fondo con la imágen temporal nº2
BitBlt TemporalDC2, 0, 0, Anchura, Altura, DestinoDC, 0, 0, SRCAND

' Copiamos la imágen temporal nº2 a la imágen de fondo
BitBlt DestinoDC, 0, 0, Anchura, Altura, TemporalDC2, 0, 0, SRCCOPY
' Sumamos la imágen temporal nº1 a la imágen de fondo
BitBlt DestinoDC, 0, 0, Anchura, Altura, TemporalDC, 0, 0, SRCPAINT

'Limpiamos el sistema
SelectObject TemporalDC, AntiguoBitMap
SelectObject TemporalDC2, AntiguoBitMap2
SelectObject MascaraDC, AntiguoMascaraBitMap
DeleteObject BitMap
DeleteObject BitMap2
DeleteObject MascaraBitMap
DeleteDC TemporalDC
DeleteDC TemporalDC2
DeleteDC MascaraDC
End Sub


Actualización 07/07/2005:
El código de aquí arríba es más limitado de lo que yo pensaba y hace cosas que no debiera, por lo que hoy que hemos estado probandolo lo hemos descartado y en su lugar he encontrado algo mucho más sencillo... La función AlphaBlend de la API de windows 98, Me, 2000 y XP:

Private Declare Function AlphaBlend _
Lib "msimg32" ( _
ByVal hDestDC As Long, _
ByVal x As Long, ByVal y As Long, _
ByVal nWidth As Long, _
ByVal nHeight As Long, _
ByVal hSrcDC As Long, _
ByVal xSrc As Long, _
ByVal ySrc As Long, _
ByVal widthSrc As Long, _
ByVal heightSrc As Long, _
ByVal dreamAKA As Long) _
As Long

.
.
.
dim numero as Long
numero=127
numero=vbBlue - CLng(numero) * (vbYellow + 1)
AlphaBlend picture2.hDC, 0, 0, picture2.ScaleWidth, picture2.ScaleHeight, picture1.hDC, 0, 0, picture2.ScaleWidth, picture2.ScaleHeight, numero

Primero colocais en la variable número un valor entre 0 (transparente) y 255 (opaco) para definir el nivel de transparencia de la imagen origen con respecto a la de destino, posteriormente con una sencilla formula (no os calenteis mucho la cabeza, ya que es una regla nemotécnica para darle un valor) se saca el valor a pasar al último parámetro de la función. Luego ya en la función le pasais el hdc de destino, el punto x e y del empiece a trabajar del destino y el ancho y alto del destino, posteriormente los mismos parámetros pero esta vez los del origen.

Funciona bastante bién y estará en todos los windows modernos.

» Leer más, comentarios, etc...

Formatos en Java con prinft

Noviembre 29th, 2004 - [Enlace local]

Con la nueva versión de Java tenemos acceso a un interpretador de formatos al estilo printf de C, mediante la clase Formatter. Es decir que con Java 5 podemos hacer lo siguiente:

Calendar c = new GregorianCalendar(1995, MAY, 23);
String s = String.format(”Cumpleaños: %1$tm %1$te,%1$tY”, c);
y obtener el resultado:

Cumpleaños: May 23, 1995
O utilizar directamente la clase Formatter:

StringBuilder sb = new StringBuilder();
Formatter formatter = new Formatter(sb, Locale.ES);
formatter.format(”Diferencia desde la última
                  declaración: € %(,.2f”, balanceDelta);
y obtener:

Diferencia desde la última declaración: € (6.217,58)
¿Pero que pasa si todavía no tenemos la posibilidad de utilizar Java 5? La respuesta pasa por utilizar alguna de las implementacíones disponibles en Java de printf.

Con las clases hechas por Henrik Bengtsson y disponibles en braju.com, podemos tener la misma funcionalidad:

Format.printf(\"%-15s %4d %6.2f%%\n\",
       new Parameters(”Donald Duck”).add(58).add(97.983));
o
Format.printf(\"%-15s %4d %6.2f%%\n\", new Object[]{\"Donald Duck\",
       new Integer(58), new Double(97.983)});
y obtener en ambos casos

Donald Duck       58  97.98%
Otra biblioteca disponible es Lava3 Printf, con similares funcionalidades.

Tanto para que nuestras salidas por consola sean mucho mas legibles como para escribir en ficheros de columnas fijas, printf es un método que se hechaba en falta pero ahora tenemos disponible en Java 5. Mientras tanto, las implementaciones disponibles en la web son mas que suficientes y ofrecen una excelente performance.

» Leer más, comentarios, etc...

Null Pointer Exception

El Futuro de los Sistemas Operativos

Noviembre 21st, 2004 - [Enlace local]

No, no voy a hablar de los ultimos avances de los sistemas operativos, ni del camino que tomará Linux en los próximos años, ni de las guerras Windows/Linux, ni de Solaris ni de ...

El caso es que mañana tengo un examen de una oposición que es muy importante para mi, y entre el temario nos podemos encontrar joyas como esta: "El futuro de los sistemas operativos de los microordenadores parece que va a ir por la predominancia del MS.DOS con Windows 3.1 ó 3.11 hasta que sea sustituido paulatinamente por Windows 95 y sus posteriores versiones y por Windows NT"

Si señor, a esto se le llama un temario actualizado.

» Leer más, comentarios, etc...

Palabras clave en el código

Noviembre 12th, 2004 - [Enlace local]

Todos los que programamos o leemos código estamos acostumbrados a leer palabras en el código como TODO o WARNING. Estas palabras son muy útiles para la documentación de nuestros programas y para encontrar puntos en los que debemos poner más atención de lo nomal a la hora de modificar.

Algunas de estas palabras más comunes son:

TODO: Indica cosas que quedan por hacer.
BUG: Da detalles de un bug que está localizado en ese punto.
WARNING: Indica que se ha de tener cuidado a la hora de hacer algo.
COMPILER: Cosas a tener en cuenta para el compilador.
KLUDGE: Indica que una solución no es elegante y que puede ser mejorada, es decir, es una chapuzilla para que la cosa funcione.
TRICKY: Indica que para llegar a la solución se ha utilizado un truco.

¿Alguien sabe alguna palabra reservada de este tipo más?

» Leer más, comentarios, etc...

Una aproximación básica a Hibernate

Noviembre 5th, 2004 - [Enlace local]

Las clases persistentes son aquellas que están relacionadas con tablas en una base de datos. Supongamos una versión simplificada de una clase Project:



public class Project {

  private Long id;

  private String name;

  private Company company;

    

  public Long getId() {

    return id;

  }

  public void setId() {

    this.id = id;

  }

  public String getName() {

    return name;

  }

  public void setName(String name) {

    this.name = name;

  }

  public Company getCompany() {

    return company;

  }

  public void setCompany(Company company) {

    this.company = company;

  }

}





en ella tenemos tres atributos: el identificador, el nombre y una referencia a Company.

El identificador, en este caso un Long, podría haber sido cualquier objeto y nos permitirá acceder a la clave primaria en la base de datos. El resto de los atributos tiene sus respectivos accesores / mutadores como cualquier JavaBean y la clase tiene definida implícitamente el constructor por defecto (sin argumentos) necesario para que Hibernate pueda hacer Constructor.newInstance().

Estas características de nuestras clases persistentes, hacen que se no dependa específicamente de ninguna tecnología de persistencia, clases o interfaces tal y como sucede con EJB y los entity beans. Por lo que podemos instanciar y comprobar el funcionamiento de la clase afuera de cualquier contenedor.

La siguiente clase, Company, la definiremos así:



public class Company {

  private Long id;

  private String name;

    

  public Long getId() {

    return id;

  }

  public void setId() {

    this.id = id;

  }

  public String getName() {

    return name;

  }

  public void setName(String name) {

    this.name = name;

  }

}





¿Como hacemos para que Hibernate persista estas clases? Definiendo (manualmente o con ayuda de herramientas) un fichero XML por clase donde especificaremos la información necesaria, y utilizando las interfaces Session y Transaction de Hibernate.

El fichero XML (XML mapping document) define de que manera las propiedades de la clase Project se corresponden con columnas de la tabla projects de la base de datos.

Para Project crearemos Project.hbm.xml en el classpath:

<?xml version=“1.0″?>
<!DOCTYPE hibernate-mapping PUBLIC
    “-//Hibernate/Hibernate Mapping DTD 2.0//EN”
    “http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd”>
<hibernate-mapping>
    <class name=“com.example.model.Project” table=“projects”>
        <id name=“id” column=“id”>
            <generator class=“native”/>
        </id>
        <property name=“name” column=“name”/>
        <many-to-one name=“company” cascade=“all” column=“company_id”/>
    </class>
</hibernate-mapping>
Y para Company crearemos Company.hbm.xml:
<?xml version=“1.0″?>
<!DOCTYPE hibernate-mapping PUBLIC
    “-//Hibernate/Hibernate Mapping DTD 2.0//EN”
    “http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd”>
<hibernate-mapping>
    <class name=“com.example.model.Company” table=“companies”>
        <id name=“id” column=“id”>
            <generator class=“native”/>
        </id>
        <property name=“name” column=“name”/>
    </class>
</hibernate-mapping>
Asumiendo que existe en nuestro classpath un fichero hibernate.properties con los parámetros de conexión a la base de datos (entre otros posibles), podremos crear un proyecto y persistirlo:



import net.sf.hibernate.Session;

import net.sf.hibernate.SessionFactory;

import net.sf.hibernate.Transaction;

import net.sf.hibernate.cfg.Configuration;

Configuration cfg = new Configuration();

cfg.addResource("Project.hbm.xml");

cfg.setPropertiesSystem.getProperties() );

SessionFactory sf = cfg.buildSessionFactory();



Session s = sf.openSession();

Transaction tx = s.beginTransaction();



Company company = new Company();

company.setName("Mi empresa");

Project project = new Project();

project.setName("MwM");

project.setCompany(company);



s.save(project);

tx.commit();

s.close();

con lo cual Hibernate generará las siguientes sentencias SQL:

insert into companies (id, name) values (1, "Mi empresa");
insert into projects (id, name, id_company) values (1, "MwM", 1);
Como se puede ver, simplemente guardando Project Hibernate guarda también, mediante cascade save, los objetos dependientes como Company.

Aunque haya sido una aproximación inicial muy básica al mundo Hibernate, esta punta del iceberg nos deja entrever muchas de las características que ofrece. Queda para otra ocasión, como hacer que Hibernate genere el esquema de base de datos y explorar en profundidad sus opciones de configuración y su idioma de query (HQL).

» Leer más, comentarios, etc...

Refactorización

Noviembre 3rd, 2004 - [Enlace local]

Hoy vía Más que código he descubierto la bitácora Refactoring en Español que cuenta trucos y consejos sobre la refactorización.

Refactorizar el código es modificarlo mejorándolo pero sin pervertir la funcionalidad del mismo y es una forma muy aconsejable de hacer los programas más eficientes y mantenibles.

Otra bitácora más para mi feedreader.

» Leer más, comentarios, etc...

Y si hablamos de...

.. mi pequeño parque de juegos

Noviembre 1st, 2004 - [Enlace local]

O al menos así debería llamarse javaHispano.net, porque estoy en 5 de los 6 proyectos más activos de esta semana :-D.

Los más activos esta semana

  1. ( 100% ) jLibrary
  2. ( 93.75% ) licurgo
  3. ( 87.5% ) hidralink
  4. ( 81.25% ) Aplicaciones de Cáñamo
  5. ( 75% ) Beleg
  6. ( 68.75% ) Cáñamo
  7. ( 62.5% ) Suite de Aplicaciones para la ASV
  8. ( 56.25% ) Juegos para Eclipse
  9. ( 50% ) Escriba.
  10. ( 43.75% ) NetTools

» Leer más, comentarios, etc...