JPanel no jogo de quebra-cabeça não atualizando

Eu tenho um jogo simples. Existe uma imagem composta por 16 mosaicos (colocados aleatoriamente). As imagens são armazenadas em uma matriz e, quando o jogo é lançado, são adicionadas ao JPanel principal.

texto alternativo http://img248.imageshack.us/img248/7403/27632947.gif

O jogo funciona desta maneira: cada imagem tem atributos ‘lugar’ e ‘número’. ‘Lugar’ é o lugar atual na grade (correto ou não) e ‘número’ é o local desejado para a imagem. Quando um usuário clica na imagem, os atributos “local” e “número” são marcados. Se eles corresponderem nada acontece. Se não, o jogo verifica se alguma imagem está atualmente na memory. Se não houver nenhum, então o ‘lugar’ e o ‘número’ desta imagem são armazenados. Se houver alguma imagem na memory, o ‘plac’e da imagem clicada no momento será verificado com o’ número ‘da imagem armazenada. Quando eles combinam – seus lugares são trocados. Esta parte funciona corretamente. Mas agora, estou chamando o método addComponent no meu JPanel com imagens atualizadas e simplesmente nada acontece. As novas imagens não deveriam ser adicionadas ao JPanel substituindo as antigas?

pacote de bônus;

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: Alterou o código para usar as respostas, mas ainda sem sorte. addComponents () obtém imagens atualizadas [], mas não as revalida.

Depois de alterar os componentes, você precisa ‘atualizar’ o componente Swing chamando invalidate() ou revalidate() .

Em vez de depender de arquivos de imagem pré-gravados, aqui está um exemplo de fatiar uma imagem existente e embaralhar as peças resultantes. Ele combina as sugestões úteis (+1) de @Frederick e @akf.

insira a descrição da imagem aqui

 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 list = new ArrayList(); 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(); } }); } } 

Você está adicionando todos os seus componentes novamente ao seu JPanel sem realmente remover nenhum deles. Em seu método addComponents() , eu primeiro chamaria removeAll() . Você pode querer renomear esse método para destacar os efeitos colaterais, já que ele não estaria mais apenas adicionando componentes. Talvez, resetComponents() seja melhor.