JPanel im Puzzle-Spiel wird nicht aktualisiert

Ich habe ein einfaches Puzzle-Spiel. Es gibt ein Bild mit 16 Kacheln (zufällig platziert). Bilder werden in einem Array gespeichert und wenn das Spiel gestartet wird, werden sie zu JPanel hinzugefügt.

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

Spiel funktioniert auf diese Weise: Jedes Bild hat Attribute “Platz” und “Nummer”. “Ort” ist der aktuelle Ort auf dem Raster (entweder korrekt oder nicht) und “Nummer” ist der gewünschte Ort für das Bild. Wenn ein Benutzer auf ein Bild klickt, werden seine Attribute ‘Ort’ und ‘Anzahl’ geprüft. Wenn sie übereinstimmen, passiert nichts. Wenn nicht, prüft das Spiel, ob ein Bild gerade im Speicher ist. Wenn es keine gibt, werden ‘place’ und ‘number’ dieses Bildes gespeichert. Wenn ein Bild im Speicher vorhanden ist, wird die Plazierung des aktuell angeklickten Bildes mit der Nummer des gespeicherten Bildes überprüft. Wenn sie zueinander passen, werden ihre Plätze getauscht. Dieser Teil funktioniert ordnungsgemäß. Aber jetzt rufe ich addComponent-Methode auf meinem JPanel mit aktualisierten Bildern auf und einfach passiert nichts. Sollten die neuen Bilder nicht zu JPanel hinzugefügt werden und die alten ersetzen?

Paket 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: Changed den Code, um die Antworten zu verwenden, aber immer noch kein Glück. addComponents () ruft aktualisierte Bilder [] auf, validiert sie jedoch nicht erneut.

   

Nach dem Ändern der Komponenten müssen Sie die Swing-Komponente aktualisieren invalidate() indem Sie invalidate() oder revalidate() aufrufen.

Anstatt sich auf vorgeschnittene Bilddateien zu verlassen, sehen Sie hier ein Beispiel für das Schneiden eines vorhandenen Bildes und das Mischen der resultierenden Teile. Es kombiniert die hilfreichen (+1) Vorschläge von @Frederick und @akf.

Bildbeschreibung hier eingeben

 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(); } }); } } 

Sie fügen alle Ihre Komponenten erneut zu Ihrem JPanel hinzu, ohne sie tatsächlich zu entfernen. In Ihrer Methode addComponents() würde ich zuerst removeAll() aufrufen. Möglicherweise möchten Sie diese Methode umbenennen, um die Nebenwirkungen hervorzuheben, da sie nicht mehr nur Komponenten hinzufügen würde. Vielleicht wäre resetComponents() besser.