java - 益智游戏中的 JPanel 未更新

标签 java swing

我有一个简单的益智游戏。有一个图像由 16 个图 block (随机放置)组成。图像存储在一个数组中,当游戏启动时,它们被添加到主 JPanel。

alt text

游戏以这种方式运行:每个图像都有属性“位置”和“数字”。 'Place' 是网格上的当前位置(正确与否),'number' 是图像所需的位置。当用户单击图像时,将检查其“位置”和“数字”属性。如果它们匹配,则什么也不会发生。如果不是,游戏会检查当前是否有任何图像在内存中。如果没有,则存储此图像的“位置”和“编号”。如果内存中有一些图像,则将当前单击图像的“位置”与存储图像的“编号”进行检查。当他们匹配时 - 他们的位置被交换。这部分工作正常。但是现在,我使用更新的图像在我的 JPanel 上调用 addComponent 方法,但什么也没有发生。不应该将新图像添加到 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;
    }
}

编辑:更改了代码以使用答案,但仍然没有运气。 addComponents() 获取更新的图像[]但不重新验证它们。

最佳答案

这里不依赖于预先剪切的图像文件,而是切片现有图像并打乱生成的片段的示例。它结合了@Frederick 和@akf 的有用 (+1) 建议。

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

关于java - 益智游戏中的 JPanel 未更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3078178/

相关文章:

java - Saxon XSLT 和 NodeList 作为参数

java - 增量运算符

java - 更改 JRadioButtons 在 JPanel 上显示的方式

Java JDialog 弄乱了 mac 上的 JMenuBar

java - Java中提取子字符串

java - junit 在 win32 下测试具有 shell 脚本功能的类

Java 组合框错误

java - 仅 jlabel 的鼠标单击事件正确更新 jlabel 文本属性

java - 复制过程中在 JTextArea 中显示

java - 主类中未调用 ActionListener?