viernes, 21 de diciembre de 2012

¡Feliz Navidad con Java!

System.out.println("¡Hola Mundo!");
Las fiestas de fin de año están a la vuelta de la esquina, y si estabas pensando en un regalo "fuera de lo común" para esta ocasión, este post te podría ayudar.

Originalmente la tarjeta surgió como una tarea/actividad en una clase de mi universidad, en la que debíamos utilizar canvas, y no solo cargar una imagen. Al final me gustó el resultado, y decidí compartir como lo había desarrollado. Entonces, al final tendremos una tarjeta como esta:



Empecemos:

Crearemos una clase llamada PanelNavidad, que extenderá de JPanel, y tendrá como atributos Images, y arreglos de enteros. PanelNavidad será una clase interna de la clase Tarjeta, la misma que extenderá de JFrame y será la ventana de nuestra aplicación.

Sobreescribimos el método paint de PanelNavidad, para dibujar los elementos que serán mostrados en la tarjeta.

class PanelNavidad extends JPanel{
        
   Image img, lazo_1, lazo_2, lazo_3, lazo_4;
   int x_1[] = new int[3]; int y_1[] = new int[3];
   int x_2[] = new int[3]; int y_2[] = new int[3];
   int x_3[] = new int[3]; int y_3[] = new int[3];
   int x_4[] = new int[3]; int y_4[] = new int[3];
        
   public PanelNavidad(){
      setPreferredSize(new Dimension(510,700));
      setBorder(BorderFactory.createLineBorder(Color.lightGray));
      setBackground(Color.WHITE);
            
      /* Agregando los puntos para poder dibujar el árbol.
       * x_n, y_n son los puntos de un triángulo, el árbol está
       * formado por 4 triángulos. */
      x_1[0] = 30; x_1[1] = 280; x_1[2] = 155;
      y_1[0] = 450; y_1[1] = 450; y_1[2] = 260;
      x_2[0] = 50; x_2[1] = 260; x_2[2] = 155;
      y_2[0] = 375; y_2[1] = 375; y_2[2] = 220;
      x_3[0] = 80; x_3[1] = 230; x_3[2] = 155;
      y_3[0] = 300; y_3[1] = 300; y_3[2] = 170;
      x_4[0] = 95; x_4[1] = 215; x_4[2] = 155;
      y_4[0] = 240; y_4[1] = 240; y_4[2] = 100;
   }
   
   //Sobreescribiendo el método paint:
   @Override
   public void paint(Graphics g){
      super.paint(g);
            
      //Dibujando el árbol.            
      g.setColor(new Color(85,52,5).darker());
      g.fillRect(130,450,50,100);            
      g.setColor(Color.GREEN.darker());            
      g.fillPolygon(x_1,y_1,3);
      g.fillOval(30,437,250,30);
      g.fillPolygon(x_2,y_2,3);
      g.fillOval(50,365,210,20);
      g.fillPolygon(x_3,y_3,3);
      g.fillOval(80,290,150,20);
      g.fillPolygon(x_4,y_4,3);
      g.fillOval(95,230,120,20);
            
      //Cargando la estrella y los lazos.
      try{
         img = ImageIO.read(ImageLoader.class.getResource("estrella.png"));
         lazo_1 = ImageIO.read(ImageLoader.class.getResource("lazo_1.png"));
         lazo_2 = ImageIO.read(ImageLoader.class.getResource("lazo_2.png"));
         lazo_3 = ImageIO.read(ImageLoader.class.getResource("lazo_3.png"));
         lazo_4 = ImageIO.read(ImageLoader.class.getResource("lazo_4.png"));
      }catch(Exception e){}                        
                       
      //Esferas de color lila
      g.setColor(new Color(128,64,144));
      g.fillOval(25,447,15,15);            
      g.fillOval(150,461,15,15);
      g.fillOval(270,447,15,15);
      g.fillOval(115,382,15,15);
      g.fillOval(250,374,15,15);
      g.fillOval(152,309,15,15);
      g.fillOval(90,240,15,15); 
      g.fillOval(205,240,15,15);
      g.fillOval(175,190,15,15);
      g.setColor(new Color(125,10,10));
      g.drawOval(25,447,15,15);            
      g.drawOval(150,461,15,15);
      g.drawOval(270,447,15,15);
      g.drawOval(115,382,15,15);
      g.drawOval(250,374,15,15);
      g.drawOval(152,309,15,15);
      g.drawOval(90,240,15,15); 
      g.drawOval(205,240,15,15);
      g.drawOval(175,190,15,15);
           
      //Esferas de color naranja
      g.setColor(new Color(255,140,0));
      g.fillOval(90,457,15,15);
      g.fillOval(215,457,15,15);
      g.fillOval(47,374,15,15);            
      g.fillOval(185,382,15,15);
      g.fillOval(75,300,15,15);
      g.fillOval(220,300,15,15);           
      g.fillOval(150,249,15,15);
      g.fillOval(120,190,15,15);
      g.fillOval(147,150,15,15);
      g.setColor(new Color(125,10,10));
      g.drawOval(90,457,15,15);
      g.drawOval(215,457,15,15);
      g.drawOval(47,374,15,15);            
      g.drawOval(185,382,15,15);
      g.drawOval(75,300,15,15);
      g.drawOval(220,300,15,15);           
      g.drawOval(150,249,15,15);
      g.drawOval(120,190,15,15);
      g.drawOval(147,150,15,15);
            
      //Lineas amarillas alrededor del arbol
      g.setColor(Color.YELLOW);            
      g.drawLine(30,447,90,457);
      g.drawLine(90,457,150,461);
      g.drawLine(150,461,215,457);
      g.drawLine(215,457,277,447);                        
      g.drawLine(50,374,115,382);
      g.drawLine(115,382,185,382);
      g.drawLine(185,382,260,374);            
      g.drawLine(78,300,160,309);
      g.drawLine(160,309,232,300);            
      g.drawLine(95,240,155,250);
      g.drawLine(155,250,215,240);            
      g.drawLine(119,187,130,190);
      g.drawLine(130,190,185,190);
      g.drawLine(185,190,193,187);            
      g.drawLine(136,147,155,150);
      g.drawLine(155,150,175,147);
            
      //----------------------
      g.setColor(Color.WHITE);
      g.setFont(new Font("Comic Sans MS",Font.ITALIC,18));
      g.drawString("<Nombre>,",235,200);
      g.setFont(new Font("Comic Sans MS",Font.ITALIC,15));
      g.drawString("La Navidad es ese niño que nace",245,230);
      g.drawString("en nuestro interior y que motiva en",240,260);
      g.drawString("nuestros corazones los sentimientos",242,290);
      g.drawString("más nobles y la esperanza por",260,320);
      g.drawString("un mundo mejor.",280,350);
      g.drawLine(280,352,390,352);
      g.drawString("¡",310,453);
      g.drawString("Feliz Navidad y",315,450);
      g.drawString("Próspero 2013! :)",355,470);             
                                    
      //Footer marrón
      g.setColor(new Color(90,60,40));            
      g.fillRect(0,550,700,560);
            
      //Dibujando los regalos y la estrella.
      g.setColor(new Color(115,30,150));            
      g.fillRect(150,510,120,120);
      g.drawImage(lazo_1,185,498,
                  lazo_1.getWidth(this),
                  lazo_1.getHeight(this),null);            
      g.setColor(new Color(120,20,10));            
      g.fillRect(30,540,100,50);
      g.drawImage(lazo_2,55,528,
                  lazo_2.getWidth(this),
                  lazo_2.getHeight(this),null);                                    
      g.setColor(new Color(240,240,60));            
      g.fillRect(80,580,80,80);                        
      g.drawImage(lazo_3,95,568,
                  lazo_3.getWidth(this),
                  lazo_3.getHeight(this),null);            
      g.setColor(new Color(25,35,100));            
      g.fillOval(200,570,80,80);                        
      g.drawImage(lazo_4,215,565,
                  lazo_4.getWidth(this),
                  lazo_4.getHeight(this),null);
      g.drawImage(img,130,80,
                  img.getWidth(this)-50,
                  img.getHeight(this)-50,null);
            
      //----------------------
      g.setColor(Color.black);
      g.setFont(new Font("Arial",Font.BOLD,15));
      g.drawString("*Click Me*",400,50);
   }                
}

Una vez creada PanelNavidad, crearemos Tarjeta. Esta clase tiene siete atributos: Point (para que nuestra tarjeta sea draggable), lienzo (objeto de tipo PanelNavidad), contenedor (JPanel de fondo), barraTitulo (JPanel), cerrar (JButton que hará la función del botón cerrar, ya que la tarjeta tendrá un estilo diferente a las ventanas normales), colores (ArrayList de Color), y un boolean, activarSonido, porque sí, nuestra tarjeta tendrá sonido.

"Jingle bells, Jingle bells, Jingle all the way..."

public class Tarjeta extends JFrame{

   Point point;
   PanelNavidad lienzo = new PanelNavidad();
   JPanel contenedor = new JPanel(new BorderLayout());
   JPanel barraTitulo = new JPanel(new GridBagLayout());
   JButton cerrar;
   ArrayList<Color> colores;
   boolean activarSonido = false;
   public Tarjeta(){        
      setSize(510,700);        
      agregarTitulo();
      agregarBotonCerrar();
      agregarColores();
      mouseListener();                
      lienzo.setBorder(BorderFactory.createLineBorder(Color.white));
      contenedor.add(lienzo,BorderLayout.CENTER);
      contenedor.add(barraTitulo,BorderLayout.NORTH);
      contenedor.setBorder(BorderFactory.createLineBorder(Color.BLACK));
      contenedor.setBackground(Color.WHITE);
      add(contenedor);        
      setLocationRelativeTo(null);
      setUndecorated(true);        
      setVisible(true);        
      this.setIconImage(new ImageIcon(ImageLoader.class.getResource("estrella.png")).getImage());
   }

Nótese que tenemos cuatro métodos dentro del constructor. "agregarTitulo" inicializa la barra de titulo, con un JLabel. "agregarBotonCerrar" añade dicho boton en la barra de título. "agregarColores" inicializa el ArrayList con 3 colores, para que luego en "mouseListener" al dar clic sobre la tarjeta, si es la primera vez, se active el sonido y cambie el color de fondo de la tarjeta, si fuese más de una vez, solo cambiaría el fondo.

public void agregarTitulo(){
   JLabel titulo = new JLabel("Hohoho... ¡Feliz Navidad! :D                                       ");
   titulo.setFont(new Font("Comic Sans MS",Font.BOLD,15));
   titulo.setForeground(Color.WHITE);                
   barraTitulo.setOpaque(false);
   barraTitulo.add(titulo);
}
    
public void agregarBotonCerrar(){
   cerrar = new JButton("X");
   cerrar.setForeground(Color.BLACK);
   cerrar.setBorder(BorderFactory.createLineBorder(Color.white));
   cerrar.setBackground(Color.WHITE);
   cerrar.addActionListener(new ActionListener(){
      @Override
      public void actionPerformed(ActionEvent e){
         System.exit(0);                
      }
   });
   barraTitulo.add(cerrar);
}

public void agregarColores(){
   colores  = new ArrayList<Color>();
   colores.add(Color.ORANGE.darker());
   colores.add(new Color(170,15,5));
   colores.add(new Color(55,70,115));
}
    
public void mouseListener(){
   point = new Point();
   contenedor.addMouseListener(new MouseAdapter(){
      @Override
      public void mousePressed(MouseEvent e){
         lienzo.setBackground(colores.get(new Random().nextInt(colores.size())));
         lienzo.setBorder(BorderFactory.createLineBorder(lienzo.getBackground()));
         contenedor.setBackground(lienzo.getBackground());
         cerrar.setBackground(lienzo.getBackground());
         cerrar.setBorder(BorderFactory.createLineBorder(lienzo.getBackground()));
         cerrar.setForeground(Color.white);                
         if(!activarSonido){
            try{
               BasicPlayer player = new BasicPlayer();
               player.open(new File("navidad.wav"));
               player.play();
            }catch(BasicPlayerException ex){
               System.out.print("Error: "+ex.getMessage());
            }
            activarSonido = true;
         }
         point.x = e.getX();
         point.y = e.getY();
      }
   });
   contenedor.addMouseMotionListener(new MouseMotionAdapter(){
      @Override
      public void mouseDragged(MouseEvent e){
         Point p = getLocation();
         setLocation(p.x + e.getX() - point.x, p.y + e.getY() - point.y);
      }
   });
}

Para reproducir el sonido, he utilizado la librería BasicPlayer3.0.
Descarga el proyecto aquí.

¡Feliz Navidad y Próspero 2013!
@DenkSchuldt.

1 comentario: