JPanel в игре-головоломке не обновляется

У меня простая игра-головоломка. Существует изображение, состоящее из 16 fragmentов (случайно помещенных). Изображения хранятся в массиве, и когда игра запускается, они добавляются к основному JPanel.

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

Игра работает следующим образом: каждое изображение имеет атрибуты «место» и «номер». «Место» – это текущее место на сетке (либо правильно, либо нет), а «номер» – это необходимое место для изображения. Когда пользователь нажимает изображение, проверяются атрибуты «место» и «номер». Если они не совпадают, ничего не происходит. Если не игра проверяет, находится ли какое-либо изображение в настоящее время в памяти. Если их нет, тогда «место» и «номер» этого изображения сохраняются. Если в памяти есть какое-то изображение, тогда «plac’e» текущего щелчка отображается с номером сохраненного изображения. Когда они совпадают – их места обмениваются. Эта часть работает правильно. Но теперь я вызываю метод addComponent на моем JPanel с обновленными изображениями и просто ничего не происходит. Не следует ли добавлять новые изображения в JPanel, заменяя старые?

бонус пакета;

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: изменил код, чтобы использовать ответы, но все равно не повезло. addComponents () получает обновленные изображения [], но не проверяет их.

После изменения компонентов вам необходимо «обновить» компонент Swing, вызвав invalidate() или revalidate() .

Вместо того, чтобы полагаться на файлы с предварительным изображением, вот пример нарезки существующего изображения и перетасовка полученных частей. Он сочетает полезные (+1) предложения как @Frederick, так и @akf.

введите описание изображения здесь

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

Вы снова добавляете все свои компоненты в свой JPanel, фактически не удаляя их. В вашем addComponents() я бы сначала вызвал removeAll() . Возможно, вы захотите переименовать этот метод, чтобы выделить побочные эффекты, поскольку он больше не будет только добавлением компонентов. Возможно, resetComponents() будет лучше.

  • Как получить индекс X и Y элемента внутри GridLayout?
  • Центрирование JLabel на JPanel
  • Java - прокрутите до определенного текста внутри JTextArea
  • JTextPane добавляет новую строку
  • как добавить разные элементы JComboBox в столбце JTable в Swing
  • Как изменить цвет подсветки сфокусированного JComboBox
  • как использовать таймер поворота для запуска / остановки анимации
  • Сохранение графического изображения Java 2d как .png-файла
  • Как перерисовать JPanel после того, как нарисовали его?
  • Как добавить JTable в JPanel с нулевой компоновкой?
  • JTable, как работаетEditor
  • Давайте будем гением компьютера.