1
votes

I have a program that displays a 4x4 grid of squares through a GridBagLayout layout manager. 16 JLabels which all contain a square.gif are displayed. When one of the rectangles is clicked, it is supposed to be replaced with a JLabel that contains an image (e.g, such as a hat). So, the image takes the place of the rectangle that is clicked on.

However, what happens at the moment is that the rectangle that is clicked only gets replaced sometimes. Other times, the rectangle disappears but the image does not replace it. Other times, the image displays in a rectangle that has been clicked previously but only after clicking a different rectangle. I have placed the most relevant code below.

public void displayGrid() {


    c.gridx = 0;
    c.gridy = 0;

    try {
        squareImage = ImageIO.read(this.getClass().getResource("stimulus(0).gif"));  //line 37

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    JLabel squareLabel = new JLabel(new ImageIcon(squareImage));

    for(int i = 0; i < 16; i++){
        c.gridx = i % 4;
        c.gridy = i / 4;
        squareLabel = new JLabel(new ImageIcon(squareImage));
        squareLabels[i] = squareLabel;
        panel.add(squareLabels[i], c);
        squareLabels[i].addMouseListener(this);

        System.out.println(c.gridx + "" + c.gridy);

    }

    panel.validate();

}

public void mousePressed(MouseEvent e) {

    for(int i = 0; i < squareLabels.length; i++){
        if(e.getSource() == squareLabels[i]){
            //JLabel removedLabel = squareLabels[i];
            c.gridx = (i/4);
            c.gridy = (i%4);
            panel.remove(squareLabels[i]);
            panel.revalidate();
            panel.repaint();
            panel.add(stimuliLabels[0], c);
            panel.validate();

        }
    }

}

In the mousePressed() method, I have attempted to write code that determines the JLabel that is pressed, gets the GridBagConstraints of that JLabel, removes the JLabel that is clicked on, and then replaces that JLabel with the new JLabel with the given GridBagConstraints. However, as I have already said, the program is not working as planned, and I don't know why.

Thank you for taking the time to read this. Any help would be appreciated.

1

1 Answers

5
votes

Why would you want to swap JLabels? JLabels are built to hold Icons, usually ImageIcons, and if you want to swap images, best to leave the JLabels in place, and simply swap the ImageIcon that it displays which is easily done by calling setIcon(...). This is much easier than what you're trying to do, and this works with the library, not against it as you're trying to do.

public void mousePressed(MouseEvent e) {
    // assuming that only JLabels are given this MouseListener:
    JLabel label = (JLabel) e.getSource();
    label.setIcon(desiredNewIcon);
}

For example, from my answer to a similar question:

import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.*;

@SuppressWarnings("serial")
public class RandomChessMen extends JPanel {
   // for this example I get a sprite sheet that holds several sprite images in it
   // the images can be found here: https://stackguides.com/questions/19209650
   private static final String IMAGE_PATH = "http://i.stack.imgur.com/memI0.png";
   private static final int LABEL_COUNT = 2;
   private static final int ICON_COLUMNS = 6;
   private Random random = new Random();

   public RandomChessMen() throws IOException {
      URL url = new URL(IMAGE_PATH);
      BufferedImage largeImg = ImageIO.read(url);
      setLayout(new GridLayout(1, 0));

      // break down large image into its constituent sprites and place into ArrayList<Icon>
      int w = largeImg.getWidth() / ICON_COLUMNS;
      int h = largeImg.getHeight() / LABEL_COUNT;
      for (int i = 0; i < LABEL_COUNT; i++) {
         final List<Icon> iconList = new ArrayList<>();
         int y = (i * largeImg.getHeight()) / LABEL_COUNT;
         // get 6 icons out of large image
         for (int j = 0; j < ICON_COLUMNS; j++) {
            int x = (j * largeImg.getWidth()) / ICON_COLUMNS;
            // get subImage
            BufferedImage subImg = largeImg.getSubimage(x, y, w, h);
            // create ImageIcon and add to list
            iconList.add(new ImageIcon(subImg));
         }

         // create JLabel
         final JLabel label = new JLabel("", SwingConstants.CENTER);
         int eb = 40;
         label.setBorder(BorderFactory.createEmptyBorder(eb, eb, eb, eb));

         // get random index for iconList
         int randomIndex = random.nextInt(iconList.size());
         Icon icon = iconList.get(randomIndex); // use index to get random Icon
         label.setIcon(icon); // set label's icon
         label.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
               Icon secondIcon = label.getIcon();
               // so we don't repeat icons
               while (label.getIcon() == secondIcon) {
                  int randomIndex = random.nextInt(iconList.size());
                  secondIcon = iconList.get(randomIndex);
               }
               label.setIcon(secondIcon);
            }
         });
         // add to GUI
         add(label);
      }
   }

   private static void createAndShowGui() {
      JFrame frame = new JFrame("RandomImages");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      try {
         frame.getContentPane().add(new RandomChessMen());
      } catch (IOException e) {
         e.printStackTrace();
         System.exit(-1);
      }
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}