// // // // // // //

viernes, 9 de enero de 2015

Trabajando con Graphics

    El funcionamiento de la clase Graphics, que es la encargada de pintar las cosas en pantalla, es muy sencillo, lo ilustraré pintando un cuadrado en una ventana. Usaré este método de Graphics: fillRect(int x, int y, int width, int height). Para usarlo, debemos obtener una instancia de Graphics, puesto que no podemos instanciarla directamente. Para hacer esto, colocaremos un JPanel dentro de un JFrame y un JButon. Al pulsar el botón ejecutaremos este método:
private void bPintarActionPerformed(java.awt.event.ActionEvent evt) { 
         
        // Obtenemos el graphics del panel en el que dibujaremos
        Graphics g = panel.getGraphics();
        // Decimos lo que dibujar y que color queremos
        g.setColor(Color.RED);
        g.fillRect(10, 10, 100, 100);
        // Lo pintamos en el panel
        panel.paintComponents(g);
}   
Y veremos que pinta correctamente un cuadrado rojo.


    Hay montones de métodos para dibujar diferentes cosas, los métodos fill hacen una figura rellena, los métodos draw solo pintan el perímetro y el método setColor indica el color que se usará hasta la siguiente vez en la que se le llame. Por ejemplo, para pintar un cuadrado rojo, y al lado solo el perímetro en azul haremos esto:
private void bPintarActionPerformed(java.awt.event.ActionEvent evt) {                                      
     
        // Obtenemos el graphics del panel en el que dibujaremos
        Graphics g = panel.getGraphics();
        // Cogemos el Rojo y pintamos el cuadrado relleno
        g.setColor(Color.RED);
        g.fillRect(10, 10, 100, 100);
       
        // Ahora el Azul y dibujamos el perimetro al lado
        g.setColor(Color.BLUE);
        g.drawRect(120, 10, 100, 100);
        // Lo pintamos en el panel
        panel.paintComponents(g);
}
    Y si queremos un cuadrado con borde negro y, por dentro verde así:
private void bPintarActionPerformed(java.awt.event.ActionEvent evt) {                                        
       
        // Obtenemos el graphics del panel en el que dibujaremos
        Graphics g = panel.getGraphics();
        // Cogemos el Rojo y pintamos el cuadrado relleno
        g.setColor(Color.GREEN);
        g.fillRect(10, 10, 100, 100);
        
        // Ahora el Azul y dibujamos el perimetro al lado
        g.setColor(Color.BLACK);
        g.drawRect(10, 10, 100, 100);
        // Lo pintamos en el panel
        panel.paintComponents(g);
    }        
    Es importante el orden, pintar primero el relleno y encima el borde, porque si no, veremos que no queda como queremos, porque se dibuja el relleno sobre el borde. Si redimensionamos la  ventana, vemos que desaparece. Esto es porque el panel se repinta, ignorando lo que hemos pintado. Para mantenerlo debemos hacer un panel que derive de JPanel y sobrescribir su método paintComponents() y en él, poner lo que queremos que se dibuje, para ello, deberíamos guardar las operaciones en algún sitio, por ejemplo, tener una clase Rectangulo con sus atributos,y guardarlos en un ArrayList, para usarlo para  pintarlo en paintComponents :
package graphics;

import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import javax.swing.JPanel;

public class Frame extends javax.swing.JFrame {

    /**
     * Creates new form Frame
     */
    public Frame() {
        initComponents();
       
        ((PanelPintado)panel).añadirRectangulo(new Rectangulo(10, 10, 100, 100, Color.RED));
        ((PanelPintado)panel).añadirRectangulo(new Rectangulo(110, 10, 100, 100, Color.BLUE));
        ((PanelPintado)panel).añadirRectangulo(new Rectangulo(210, 10, 100, 100, Color.GREEN));
       
    }

// Aquí están los métodos que hace NetBeans.
}

class PanelPintado extends JPanel{

    ArrayList<Rectangulo> rectangulos;

    public PanelPintado() {
       
        this.rectangulos = new ArrayList();
    }
   
    public boolean añadirRectangulo(Rectangulo r){
       
        return rectangulos.add(r);
    }
   
    @Override
    protected void paintComponent(Graphics g) {
        // Primero llamamos al paintComponents que dibujará el JPanel
        super.paintComponent(g);
        // Encima del JPanel pintamos los rectangulos
        for(Rectangulo r : rectangulos){
            g.setColor(r.getColor());
            g.fillRect(r.getX(), r.getY(), r.getAncho(), r.getAlto());
        }
        // Si cambiamos el orden se pinta el fondo del JPanel sobre los rectangulos y no se ven
    }  
}

class Rectangulo{
   
    int x,y,ancho,alto;
    Color color;

    public Rectangulo(int x, int y, int ancho, int alto, Color color) {
        this.x = x;
        this.y = y;
        this.ancho = ancho;
        this.alto = alto;
        this.color = color;
    }
   
    public int getX() {return x;}
    public int getY() {return y;}
    public int getAncho() {return ancho;}
    public int getAlto() {return alto;}
    public Color getColor() {return color;}
   
}
    Si queremos hacerlo en NetBeans, debemos crear un JFrame con un JPanel que se llame panel y añadir las dos clases al final de la clase, después del último “}”, por último para cambiar el JPanel, una vez puesto, para que sea un PanelPintado, en la vista diseño, hacemos click derecho > personalizar código y cambiamos la primera linea por  panel = new PanelPintado();  Como NetBeans deja la definición de los campos como si fuera un JPanel, necesitamos esos cast del principio para añadir los rectángulos.

    El ejemplo está hecho deprisa y corriendo, lo que importa es el override de la clase JPanel y el hecho de guardar las operaciones para que se repinten. Si queremos que lo que dibujemos sea proporcional al panel deberemos guardar porcentaje en vez del tamaño en pixeles.

  Y hasta aquí un pequeño ejemplo de cómo usar la clase Graphics, si sabéis mejorarlo, por favor, comentad, que es la mejor manera de aprender.


No hay comentarios:

Publicar un comentario