Dalam permainan teka-teki mudah, imej yang mewakili jubin diletakkan secara rawak pada grid. Setiap imej mempunyai atribut 'tempat' dan 'nombor' yang menunjukkan kedudukan semasa dan yang dikehendaki. Logik permainan menukar imej yang sepadan dengan 'nombor' dengan betul dan mengemas kini atribut 'tempat' mereka. Walau bagaimanapun, menambah imej yang dikemas kini pada JPanel tidak mengemas kini grid yang dipaparkan.
Untuk menangani isu ini, kami akan mengubah suai kaedah addComponent() untuk memuat semula JPanel dengan betul:
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]); } // Explicitly revalidate and repaint the JPanel this.revalidate(); this.repaint(); }
Dengan menggunakan revalidate() dan repaint(), kami memaksa JPanel untuk mengira semula susun aturnya dan mengemas kini paparan dengan yang baharu imej.
Sebagai alternatif, pertimbangkan contoh kod berikut, yang menggunakan pendekatan yang lebih cekap:
import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.GridLayout; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; import javax.swing.Timer; import javax.swing.WindowConstants; public class PuzzleGame { private static final int N = 4; private final JPanel panel = new JPanel(new GridLayout(N, N)); private final JButton[][] buttons = new JButton[N][N]; private final BufferedImage image; private PuzzleGame() throws IOException { image = ImageIO.read(new File("image.jpg")); createButtons(); JFrame frame = new JFrame(); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.add(panel); frame.pack(); frame.setVisible(true); // Timer to simulate image swapping Timer timer = new Timer(1000, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { shuffleButtons(); } }); timer.start(); } private void createButtons() { int count = 0; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { buttons[i][j] = new JButton(); buttons[i][j].setPreferredSize(new Dimension(50, 50)); int w = image.getWidth() / N; int h = image.getHeight() / N; BufferedImage subImage = image.getSubimage(j * w, i * h, w, h); buttons[i][j].setIcon(new ImageIcon(subImage)); panel.add(buttons[i][j]); buttons[i][j].addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { JButton b = (JButton) e.getSource(); // Swap logic here } }); count++; } } } private void shuffleButtons() { Container parent = panel.getParent(); if (parent != null) { panel.remove(buttons[0][3]); parent.add(buttons[0][3], 0); } // Update the UI panel.revalidate(); panel.repaint(); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { new PuzzleGame(); } catch (IOException e) { e.printStackTrace(); } } }); } }
Kod ini mencipta butang imej yang dihiris dan menyimpannya dalam grid 4x4. Pemasa merangsang pengocokan imej dengan menggerakkan butang kanan atas ke kedudukan pertama. Kaedah revalidate() dan repaint() memastikan UI dikemas kini dengan betul selepas setiap pergerakan butang.
Atas ialah kandungan terperinci Mengapakah JPanel Saya Tidak Kemas Kini Selepas Menambah atau Mengalih Imej dalam Permainan Teka-teki?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!