jueves, 31 de mayo de 2012

La clase Graphics

Casi todas las componentes y contenedores de Swing tienen un método paint(g) asociado que sirve para dibujarlos en pantalla. Java invoca este método automáticamente cuando tiene que mostrar, de forma estándar, la componente o contenedor en cuestión (esto es, sus bordes, su título, si lo tiene, etc.)
El método paint(g) se redefine cuando se quiere que estos elementos tengan un aspecto particular, por ejemplo, cuando se quiere dibujar algo específico sobre ellos.
El método paint(g) es de la forma

public void paint(Graphics g) {
...
}

Donde g es un objeto de la clase abstracta Graphics. Todo contenedor o componente que se pueda dibujar en pantalla tiene asociado un objeto g de esta clase, con la información sobre el área de la pantalla que el
contenedor o la componente cubre. Además, el objeto g dispone de métodos para hacer gráficos (dibujar círculos, rectángulos, líneas, etc.)

La clase Graphics se importa de awt:

import java.awt.*;

Cuando el método paint(g) se ejecuta es porque ha sido invocado por otros métodos, nunca invocado por
nosotros, y el parámetro que usa corresponde a un objeto de la clase Graphics asociado al contenedor o
componente que estemos manejando.
Cuando se redefine el método paint(g), siempre se comienza con una invocación super.paint(g) al método de la superclase, asegurando así que se dibuja la parte estándar del contenedor o componente que estemos manejando.

Por ejemplo, vamos a dibujar una cara en un marco. Un marco es un elemento de la clase JFrame y para dibujar en él procedemos así:


public void paint (Graphics g){
      super.paint(g);
      
      //Dibujo el contorno de la cara
      g.setColor(Color.BLACK);
      g.fillOval(105, 70, 100, 100);
      
      //Dibujo de los ojos
      g.setColor(Color.GREEN);
      g.fillOval(125, 100, 10, 10);
      g.fillOval(175, 100, 10, 10);
      
      //Dibujo de la nariz
      g.drawLine(150, 100, 150, 130);
      
      //Dibujo de la boca
      g.drawArc(118, 120, 75, 30, 180, 180);
    }

Para entender lo que ha hecho el método anterior hay que saber que:
  • El sistema de coordenadas de un contenedor tiene su origen en su esquina superior izquierda.
  • Las abscisas se incrementan hacia la derecha y las ordenadas hacia abajo.
  • Cada punto es un píxel.
  • En general, el dibujo de una figura (rectángulo, elipse, rectángulo redondo, etc.) se realiza dando las coordenadas de la esquina superior izquierda de un rectángulo imaginario que la contiene.
Algunos métodos de la clase Graphics para dibujar figuras son:
  • drawLine(x1,y1,x2,y2): dibuja una línea recta desde el punto (x1,y1) al punto (x2,y2)
  • fillRect(x,y,ancho,alto): rellena el rectángulo que tiene su esquina superior izquierda en (x,y) y el ancho y largo dados
  • drawOval(x,y,ancho,alto): dibuja una elipse contenida en un rectángulo imaginario cuya esquina superior izquierda está en (x,y) y tiene el ancho y largo dados
  •  fillOval(x,y,ancho,alto): rellena la elipse especificada pordrawOval(x,y,ancho,largo)
  • drawArc(x,y,ancho,alto, inicioAngulo,barridoAngulo): dibuja parte de una elipse dentro de un rectángulo imaginario cuya esquina superior izquierda está en (x,y), tiene el largo y ancho dados, empieza a dibujar en el ángulo inicioAngulo y hace un barrido de barridoAngulo
  • setColor(Color.red): cambia la “tinta” del objeto g y la pone de color rojo. La clase Color se importa de awt:
                                        import java.awt.*;

Dibujar sobre paneles

  • Cuando se actualiza un componente, se borra su aspecto actual y seinvoca paint(g). El borrado previo puede producir parpadeo (flickering) ,por lo que a veces el método paint(g) evita hacerlo.
  • Sin embargo, la actualización puede necesitar hacer el borrado previo(para actualizar el fondo del componente, por ejemplo). En estos casos se invoca el método paintComponent(g) de la clase JComponent, que permite hacer un barrido previo, pero usando la técnica del doble buffer para eliminar el parpadeo.
  • En casos como los anteriores lo que se hace es redefinir el método paintComponent(g) en lugar del método paint(g).
Por ejemplo, para dibujar la cara que pintamos antes, pero sobre un (j)panel en lugar de sobre un marco, hacemos lo siguiente:
  • Se declara la clase PanelCara que extiende la clase JPanel, como clase (privada) de la clase MarcoCara que habíamos creado antes
  • Se redefine el método paintComponent(g) usando las mismas instrucciones que antes, pero llamando inicialmente a super.paintComponent(g)
                       public void paintComponent(Graphics g) {
                          super.paintComponent(g);...}

Cuando el contenido de un marco o panel cambia, el método repaint() se encarga de actualizar el contenedor y mostrarlo por pantalla, invocando implícitamente el método paint(g) o paintComponent(g).
Por ejemplo, para añadir un botón al marco que mostraba una cara sonriente de forma que, cuando se pulse, la cara cambie a una cara eenojada, basta hacer lo siguiente:
  • Se añade a contentPane el botón cuyo efecto cambiará la sonrisa de la cara
  • Se añade un atributo booleano al marco que indica si la cara sonríe o no 
                   private boolean sonrie=true;
  • Dentro del actionPerformed del boton codeamos lo siguiente:
                   sonrie=!sonrie;
                   repaint();
  • El método paintComponent(g) para pintar el panel se redefine por el siguiente:
                   public void paintComponent(Graphics g) {
                        super.paintComponent(g);
                          //Dibujo de la cara igual que antes, salvo la boca
                            ...
                              //Dibujo de la boca
                                if (sonrie) g.drawArc(118, 125, 75, 30, 180, 180);
                                  else g.drawArc(118, 125, 75, 30, 180, -180);
                                    }

                Dibujar texto

                La clase Graphics permite “dibujar” texto, como alternativa al texto mostrado en los componentes JLabel, JTextField y JTextArea. El método que permite graficar texto sobre el JFrame es:

                drawString(String str, int x, int y);

                Clase Color

                La clase java.awt.Color encapsula colores utilizando el formato RGB (Red, Green, Blue). Las componentes de cada color primario en el color resultante se expresan con números enteros entre 0 y 255, siendo 0 la intensidad mínima de ese color y 255 la máxima. En la clase Color existen constantes para colores predeterminados de uso frecuente: black, white, green, blue, red, yellow, magenta, cyan, orange, pink, gray, darkGray, lightGray.

                Presentación de imágenes

                Java permite incorporar imágenes de tipo GIF y JPEG definidas en ficheros. Se dispone para ello de la clase java.awt.Image. Para cargar una imagen hay que indicar la localización del archivo y cargarlo mediante el método getImage(). Este método existe en las clases java.awt.Toolkit.
                Entonces, para cargar una imagen hay que comenzar creando un objeto (o una referencia) Image y llamar al método getImage() (de Toolkit); Una vez cargada la imagen, hay que representarla, para lo cual se redefine el método paint() para llamar al método drawImage() de la clase Graphics. Los objetos Graphics pueden mostrar imágenes a través del método: drawImage(). Dicho método admite varias formas, aunque casi siempre hay que incluir el nombre del objeto imagen creado.

                Clase Image

                Una imagen es un objeto gráfico rectangular compuesto por pixels coloreados. Cada pixel en una imagen describe un color de una particular localización de la imagen.
                A continuación, algunos métodos de la clase Image:
                La clase Graphics provee el método drawImage() para dibujar imagenes; este método admite varias formas:

                - drawImage (Image i, int x, int y, ImageObserver o)
                - drawImage (Image i,int x,int y,int width,int height,ImageObserver o)

                Un ejemplo del metodo paint(Graphics G) para traer una imagen de la carpeta raiz es el siguiente:

                                    public void paint (Graphics g)
                                    {
                                    super.paint(g);
                                    Toolkit t = Toolkit.getDefaultToolkit ();
                                    Image imagen = t.getImage ("imagen1.jpg");
                                    g.drawImage (imagen, 0, 0, this);
                                    }

                22 comentarios:

                1. Disculpa el nos podrias colocar el ejemplo completo e sdecir con codigo y visualizacion de lo anterior. gracias

                  ResponderEliminar
                  Respuestas
                  1. hahahaha ponte a estudiar y deja de mendigar codigos

                    Eliminar
                  2. Algunos tratamos de aprender, idiota, por eso eso estamos aqui

                    Eliminar
                  3. Estuvo bien explicado amigo, solo es cuestion de leer y releer

                    Eliminar
                2. La practica hacen al programador...

                  ResponderEliminar
                3. hola buen aporte tengo una consulta e creado un jframe con el editor de netbeans y dentro del jframe varios jpanel uno de ellos es mi lienso para pintar el problema que tengo como escribir el metodo paint de lineso

                  gracias de antemano

                  ResponderEliminar
                4. Este comentario ha sido eliminado por el autor.

                  ResponderEliminar
                5. alguien me puede ayudar con este programa, me marca que no se a declarado la clase principal y ya puse el public static void main(String[] args) y si lo corre pero no pone nada


                  import java.awt.*;
                  import java.applet.*;
                  public class Resultadosexamenes extends Applet{

                  public void paint(Graphics g) {



                  double promedio=5;
                  Font font=new Font("TimesRoman",Font.BOLD,18);
                  g.setFont(font);
                  if(promedio>=9)
                  g.drawString("Tienes exelente nivel de conocimiento!",20,80);

                  else
                  if(promedio>=8 && promedio<=9)
                  g.drawString("Tienes buen nivel de conocimiento!",20,80);

                  else
                  if(promedio>=8 && promedio<=9)
                  g.drawString("Tienes nivel de conocimiento regular!",20,80);

                  else
                  if(promedio>=8 && promedio<=9)
                  g.drawString("Tienes que estudiar más!",20,80);

                  else
                  if(promedio>=8 && promedio<=9)
                  g.drawString("Reprobaste!",15,50);
                  }


                  }

                  ResponderEliminar
                  Respuestas
                  1. Hey, ¿ya lo resolviste, amigo?... No lo corras con el ícono de play(de color verde) que aparece en NetBeans... Debes de colocarte en el código de tu programa y darle clic derecho y darle otro clic en RunTime… Debe correr, a pesar de que no tengas clase main (principal).

                    Eliminar
                6. alguien me puede ayudar con este programa, me marca que no se a declarado la clase principal y ya puse el public static void main(String[] args) y si lo corre pero no pone nada


                  import java.awt.*;
                  import java.applet.*;
                  public class Resultadosexamenes extends Applet{

                  public void paint(Graphics g) {



                  double promedio=5;
                  Font font=new Font("TimesRoman",Font.BOLD,18);
                  g.setFont(font);
                  if(promedio>=9)
                  g.drawString("Tienes exelente nivel de conocimiento!",20,80);

                  else
                  if(promedio>=8 && promedio<=9)
                  g.drawString("Tienes buen nivel de conocimiento!",20,80);

                  else
                  if(promedio>=8 && promedio<=9)
                  g.drawString("Tienes nivel de conocimiento regular!",20,80);

                  else
                  if(promedio>=8 && promedio<=9)
                  g.drawString("Tienes que estudiar más!",20,80);

                  else
                  if(promedio>=8 && promedio<=9)
                  g.drawString("Reprobaste!",15,50);
                  }


                  }

                  ResponderEliminar
                7. alguien me puede ayudar con este programa, me marca que no se a declarado la clase principal y ya puse el public static void main(String[] args) y si lo corre pero no pone nada


                  import java.awt.*;
                  import java.applet.*;
                  public class Resultadosexamenes extends Applet{

                  public void paint(Graphics g) {



                  double promedio=5;
                  Font font=new Font("TimesRoman",Font.BOLD,18);
                  g.setFont(font);
                  if(promedio>=9)
                  g.drawString("Tienes exelente nivel de conocimiento!",20,80);

                  else
                  if(promedio>=8 && promedio<=9)
                  g.drawString("Tienes buen nivel de conocimiento!",20,80);

                  else
                  if(promedio>=8 && promedio<=9)
                  g.drawString("Tienes nivel de conocimiento regular!",20,80);

                  else
                  if(promedio>=8 && promedio<=9)
                  g.drawString("Tienes que estudiar más!",20,80);

                  else
                  if(promedio>=8 && promedio<=9)
                  g.drawString("Reprobaste!",15,50);
                  }


                  }

                  ResponderEliminar
                8. es que eres un wey ya matate

                  ResponderEliminar
                9. si ya matate.
                  echale miel xD
                  100% REAL NO FAKE

                  ResponderEliminar
                10. no sirve la chingadera
                  100% REAL NO FAKE

                  ResponderEliminar
                11. Una alternativa al primer suepr.paint(g);
                  Es hacerlo de la siguiente manera:
                  public void paint(Graphics g){
                  // super.paint(g);
                  Graphics2D nuevoG = (Graphics2D) g;
                  // Aca tu codigo, como por ejmp
                  nuevoG.drawString("Hola", 10, 10);
                  }

                  ResponderEliminar
                12. :V pinches webones ponganse a leer :V y pues no sean culos con los que estan iniciando en la programacion

                  ResponderEliminar
                13. alguien me puede ayudar con este codigo?
                  if (!(!(!(!(!(x!=y)))))){
                  //hacer algo
                  }

                  ResponderEliminar
                14. muchas gracias, informacion muy util!!, saludos!!

                  ResponderEliminar