23 febrero 2006

updateUI

Creía tener controlado el tema de repintados en java. Cuando hacía algo con una ventana (modificar los datos, pintar gráficos, etc, etc) simplemente había que llamar al método repaint(). Este método nofifica a la máquina virtual que el componente necesita repintado. Más adelante, cuando la máquina virtual lo dispone y en un hilo separado, se llama al método paint(Graphics) del componente para que este se pinte.

Sin embargo, encontré un pequeño problema que me ha traido loco durante un buen rato. Resulta que si al hacer una ventana hago esto

ventana = new Ventana();
ventana.add (los botones);
ventana.setVisible(true);

todo va estupendo. Pero si altero el orden

ventana = new Ventana();
ventana.setVisible(true);
ventana.add (los botones);

no hay manera de que se pinten los botones. Por más cosas que he intentado (añadir repaint() al final), no hay manera de que pinten nuevos componentes sobre una ventana ya visible. Al redimensionar la ventana con el ratón, los componentes aparecen de golpe.

Finalmente, gracias a un compañero de trabajo, descubrí el método updateUI(). Este método sí dibuja realmente todos los componentes.

ventana = new Ventana();
ventana.setVisible(true);
ventana.add (los botones);
ventana.updateUI();

09 febrero 2006

Un botón girado

En java podemos heredar de JButton o cualquier otro componente y redefinir el método paint() para que el componente se dibuje como queramos.

Una opción fácil usando la clase AffineTransform consiste en hacer que el botón se gire, por ejemplo 45 grados. El siguiente código de ejemplo hace eso precisamente. Muestra una ventana con un botón girado 45 grados.

package chuidiang.ejemplos;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.WindowConstants;

public class EtiquetaGirada extends JButton
{
public void paint (Graphics g)
{
// Para girar
AffineTransform at = new AffineTransform();
at.scale(0.6,0.6); // Se reduce el tamaño para que quepa girado
at.translate (80,0); // Se traslada para que quede centrado
at.rotate(45*Math.PI/180); // Se rota 45 grados
((Graphics2D)g).setTransform(at);
super.paint(g);
}

public Dimension getPreferredSize()
{
return new Dimension (100,100);
}

public static void main(String [] args)
{
JFrame v = new JFrame();
v.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
EtiquetaGirada l= new EtiquetaGirada();
l.setText("hola");
l.setFont(l.getFont().deriveFont((float)30.0));
v.getContentPane().setLayout(new FlowLayout());
v.getContentPane().add(l);
v.pack();
v.setVisible(true);
}
}

Y este es el resultado



Bueno, no queda demasiado allá, pero es cuestión de arreglarlo un poquito.

06 febrero 2006

Juntar ramas en cvs

Lo prometido es deuda. Comenté que había hecho una rama en cvs y que iba a poner una nueva entrada en este diario cuando las juntara. Bien, ya lo he hecho.

El mecanismo es sencillo, aunque puede ser un poco tedioso si hemos dejado pasar mucho tiempo desde que hicimos la rama hasta que juntamos.

Para juntar la rama con la rama principal, nos situamos en la rama principal con

cvs udpate -A

Luego le decimos a cvs que nos haga un update de la rama mezclándolo que lo que tenemos fuera. Eso se hace con update y la opción -j

cvs update -j etiqueta_rama

Esto nos junta todos los ficheros. Debemos prestar atención a la salida para ver de qué ficheros se ha hecho "merge" (mezcla de las dos ramas). Debemos resolver todos esos "merge" a mano, es decir, editando el fichero con el editor y arreglandolo.

Finalmente, hacemos un commit de todos los cambios

cvs commit -m"Juntadas las ramas"

05 febrero 2006

Una pena de foro

Hay dos páginas con foros que suelo visitar con frecuencia: http://www.programacion.com y http://www.lawebdelprogramador.com, en concreto, suelo visitar los foros de C/C++ y de java.

Hay uno sin embargo que me ha decepcionado desde hace un tiempo, es el de C/C++ de http://www.programacion.com/foros/29. Se ha convertido en un foro de "quiero que alguien me haga los deberes" y parece más un listado de problemas de clase que un foro de programación.

Hay un par de post: "HEY SI ALGUIEN NECESITA ALGUN PROGRAMA" y "Tengo varios programas en C++" que llevan más de 500 posts y aparecen en la primera página del foro desde hace ya no sé cuánto tiempo.

Estaría bien, por un lado, que la gente se esforzara un poco con sus deberes de clase y no los pidieran hechos. En el 99% de los casos es inútil pedirlos (nadie contesta) y molestan a los que vamos a aprender y resolver dudas concretas.

Como esto es casi imposible, también estaría bien que los moderadores del foro pusieran límite a este tipo de cosas. Para no perder visitas, podrían poner un foro separado de "tareas de clase" y mover allí todos los posts de este estilo.

En fin, que desde que eso es así, prácticamente no visito ese foro.

03 febrero 2006

Hacer ramas en cvs

Encontré un tutorial de cvs avanzado en el que explica bastante bien el tema de hacer ramas: http://es.tldp.org/Manuales-LuCAS/doc-cvsbook-es/cvsbook-html/CVS-avanzado.html#CVS%20avanzado

Aprovechando en el trabajo que tuve que hacer un cambio más o menos importante, hice una rama y de paso probé todo el tema este.

Para hacer la rama, siguiendo el tutorial, hay que dar los siguientes pasos:
  • Marcar la versión actual con una etiqueta. No es obligatorio, pero de esta forma se puede obtener la versión de justo antes de hacer la nueva rama. Situándose lo más arriba posible en la estructura guardada en cvs, se ejecuta el comando
    cvs tag etiqueta_antes_rama
  • Luego se crea la rama, dándole una nueva etiqueta. El comando es
    cvs tag -b etiqueta_rama
  • Ya está creada. El que quiera trabajar en la nueva rama debe sacar esta versión con el comando
    cvs update -r etiqueta_rama
    Todo los commit y update que haga desde este momento, se harán en la rama nueva.
  • Para volver a la rama principal, se ejecuta el comando
    cvs update -A
    La opción -A saca los ficheros de la rama por defecto de CVS, que si no hemos hecho nada en contra, es la rama principal.
    No podemos hacer cvs update -r etiqueta_antes_rama porque nos sacaría justo los ficheros con esa etiqueta y no los más modernos de esa rama.
Podemos cambiar de rama siempre que nos interese. Me ha llamado la atención al hacerlo que si en una rama borro ficheros y en la otra no, los ficheros se me borran o recuperan según hago update de una rama o de otra.

Cuando en el trabajo junte ambas ramas y experimente con el tema, volveré a poner un post sobre cómo juntar ramas.