java - 无法使用 GridBagLayout 将 JLabel 替换为其他 JLabel

标签 java swing jlabel layout-manager gridbaglayout

我有一个程序可以通过 GridBagLayout 布局管理器显示 4x4 正方形网格。显示全部包含 square.gif 的 16 个 JLabel。单击其中一个矩形时,应该将其替换为包含图像(例如帽子)的 JLabel。因此,图像取代了被点击的矩形。

但是,目前发生的情况是,单击的矩形有时只会被替换。其他时候,矩形会消失,但图像不会替换它。其他时候,图像显示在先前已单击但仅在单击不同矩形之后的矩形中。我在下面放置了最相关的代码。

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

        }
    }

}

在 mousePressed() 方法中,我试图编写代码来确定按下的 JLabel,获取该 JLabel 的 GridBagConstraints,删除被点击的 JLabel,然后用具有给定 GridBagConstraints。然而,正如我已经说过的,该程序没有按计划运行,我不知道为什么。

感谢您花时间阅读本文。任何帮助将不胜感激。

最佳答案

为什么要交换 JLabel? JLabels 是用来保存图标的,通常是 ImageIcons,如果你想交换图像,最好将 JLabels 留在原地,并简单地交换它显示的 ImageIcon,这很容易通过调用 setIcon(...)。这比您尝试做的要容易得多,而且这适用于库,而不是像您尝试做的那样反对它。

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

例如,来 self 对 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://stackoverflow.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();
         }
      });
   }
}

关于java - 无法使用 GridBagLayout 将 JLabel 替换为其他 JLabel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36974304/

相关文章:

java - JLabel 与 JFrame 不完全一致

java - 旋转矩形后得到一个点

java - DocumentListener 会减慢 Document.setCharacterAttributes 方法的速度吗?

java - 如何使用 Java Swing 取消选择和撤消复选框?

java - 让 MouseListener 本身改变他正在监听的对象

java - JLabel 在 JFrame 中不显示任何内容

java - 维护引用然后分配新对象线程安全吗?

java - 如何获取jar文件内的文件夹路径?

java - 如何从 iserialnumber 获取 USB 设备序列号?

java - 如何在 swing 中制作齐平的 JButton?