2010-06-20 7 views
6

Tengo un juego de rompecabezas simple. Hay una imagen que consiste en 16 fichas (colocadas al azar). Las imágenes se almacenan en una matriz y cuando se inicia el juego se agregan al JPanel principal.JPanel en juego de rompecabezas no está actualizado

alt text http://img248.imageshack.us/img248/7403/27632947.gif

juego funciona de esta manera: Cada imagen tiene atributos 'lugar' y 'número'. 'Lugar' es el lugar actual en la cuadrícula (ya sea correcto o no) y 'número' es el lugar deseado para la imagen. Cuando un usuario hace clic en la imagen, se verifican sus atributos de "lugar" y "número". Si coinciden, no pasa nada. Si no es el juego, comprueba si alguna imagen está actualmente en la memoria. Si no hay ninguno, se almacenan el "lugar" y el "número" de esta imagen. Si hay alguna imagen en la memoria, entonces se marca el "lugar" de la imagen actualmente seleccionada con el "número" de la imagen almacenada. Cuando coinciden, sus lugares se intercambian. Esta parte funciona correctamente Pero ahora, estoy llamando al método addComponent en mi JPanel con imágenes actualizadas y simplemente no pasa nada. ¿Las nuevas imágenes no deberían agregarse a JPanel reemplazando las antiguas?

paquete Bonus;

import javax.swing.*; 
import java.util.Random; 
import java.awt.event.*; 
import java.awt.*; 

class Puzzle extends JPanel implements ActionListener { 
    private int selected_nr=-1; 
    private int selected_pl=-1; 
    private boolean memory=false; 
    private static Img[] images; 

    public Puzzle(){ 
     JFrame f = new JFrame("Smile"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(this); 
     f.setSize(252,252); 
     f.setVisible(true); 

     setLayout(new GridLayout(4, 4)); 
     images = new Img[16]; 
     int[] buttons = new int[16]; 

     for(int i=0; i<16; i++){ 
      buttons[i] = i; 
     } 

     int rand; 
     int temp; 
     Random random; 

     random = new Random(System.currentTimeMillis()); 
     for (int i = 0; i < buttons.length; i++) { 
      rand = (random.nextInt() & 0x7FFFFFFF) % buttons.length; 
      temp = buttons[i]; 
      buttons[i] = buttons[rand]; 
      buttons[rand] = temp; 
     } 

     for (int i = 0; i < 16; i++) { 
      images[i] = new Img(i, buttons[i]); 
     } 
     addComponents(images); 
    } 

    public void addComponents(Img[] im){ 
     this.removeAll(); 
     for(int i=0; i<16; i++){ 
      im[i].addActionListener(this); 
      im[i].setPreferredSize(new Dimension(53,53)); 
      add(im[i]); 
     } 
     this.validate(); 
    } 

    public void actionPerformed(ActionEvent e) { 
     Img b = (Img)(e.getSource()); 
     int num = b.getNumber(); 
     int pl = b.getPlace(); 

     if(!(b.rightPlace())){ 
      if(memory){ 
       if(pl == selected_nr){ 
        images[pl].setPlace(selected_pl); 
        images[selected_pl].setPlace(selected_nr); 
        selected_nr = -1; 
        selected_pl = -1; 
        memory = false; 
        addComponents(images); 
       } 
       else{ 
        System.out.println("Try other image"); 
       } 
      } 
      else{ 
       memory = true; 
       selected_nr = num; 
       selected_pl = pl; 
      } 
     } 
     else{ 
      System.out.println("OK !"); 
     } 
    } 

    public static void main(String args[]) { 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       new Puzzle(); 
      } 
     }); 
    } 
} 

class Img extends JButton { 
    int number; 
    int place; 
    ImageIcon img; 

    public Img(int p, int n){ 
     number = n; 
     place = p; 
     img = new ImageIcon("u"+number+".jpg", BorderLayout.CENTER); 
     setIcon(img); 
    } 

    public boolean rightPlace(){ 
     boolean correct=false; 
     if(number == place){ 
      correct = true; 
     } 
     return correct; 
    } 
    public void setPlace(int i){ 
     place = i; 
    } 
    public int getNumber(){ 
     return number; 
    } 
    public int getPlace(){ 
     return place; 
    } 
} 

EDIT: Se ha cambiado el código para utilizar las respuestas, pero aún ninguna suerte. addComponents() obtiene imágenes actualizadas [] pero no las vuelve a validar.

+0

Considere 'aleatoria = new Random()'. – trashgod

+0

Bien, obtuve el error. Simplemente necesitaba cambiar lugares de imágenes en imágenes []. Ahora funciona. – DevAno1

Respuesta

3

Después de cambiar los componentes, necesita 'actualizar' el componente Swing llamando al invalidate() o revalidate().

4

Está agregando todos sus componentes nuevamente a su JPanel sin eliminar ninguno de ellos. En su método addComponents(), primero llamaría al removeAll(). Es posible que desee cambiar el nombre de ese método para resaltar los efectos secundarios, ya que no solo agregará componentes. Quizás, resetComponents() sería mejor.

10

En lugar de confiar en los archivos de imágenes precortadas, aquí hay un ejemplo de cortar una imagen existente y mezclar las piezas resultantes. Combina las sugerencias útiles (+1) de @Frederick y @akf.

enter image description here

import java.awt.EventQueue; 
import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.Collections; 
import java.util.List; 
import javax.imageio.ImageIO; 
import javax.swing.ImageIcon; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.Timer; 

public class ImageLabelPanel extends JPanel implements ActionListener { 

    private static final int N = 4; 
    private final List<JLabel> list = new ArrayList<JLabel>(); 
    private final Timer timer = new Timer(1000, this); 

    ImageLabelPanel() { 
     this.setLayout(new GridLayout(N, N)); 
     BufferedImage bi = null; 
     try { 
      bi = ImageIO.read(new File("image.jpg")); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     for (int r = 0; r < N; r++) { 
      for (int c = 0; c < N; c++) { 
       int w = bi.getWidth()/N; 
       int h = bi.getHeight()/N; 
       BufferedImage b = bi.getSubimage(c * w, r * h, w, h); 
       list.add(new JLabel(new ImageIcon(b))); 
      } 
     } 
     createPane(); 
     JFrame f = new JFrame(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(this); 
     f.pack(); 
     f.setVisible(true); 
     timer.start(); 
    } 

    private void createPane() { 
     this.removeAll(); 
     for (JLabel label : list) add(label); 
     this.validate(); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     Collections.shuffle(list); 
     createPane(); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new ImageLabelPanel(); 
      } 
     }); 
    } 
}