我正在尝试将相同的jlabel存储的图像两次加载到gridlayout面板中,但是该图像仅显示一次然后移动,而不是创建图像的两个实例。

如何将Pieces数组中的相同JLabel位置存储到boardLabels数组中的多个JLabel中。

谢谢 :)

public static JPanel boardPanel = new JPanel(new GridLayout(4, 0));
public static JLabel pieces[] = new JLabel[2];
private static JLabel[] boardLabels = new JLabel[4];

public MainFrame() {
    pieces[0] = new JLabel(new ImageIcon(System.getProperty("user.dir") + "/images/piece1.png"));
    pieces[1] = new JLabel(new ImageIcon(System.getProperty("user.dir") + "/images/piece2.png"));

    this.add(boardPanel);
    displayGUIboard();
}


public static void displayGUIboard() {

    //ERROR - the label in pieces[0] is not copied into both boardLabels [0] and [1]
    boardLabels[0] = pieces[0];
    boardLabels[1] = pieces[0];

    boardPanel.add(boardLabels[0]);
    boardPanel.add(boardLabels[1]);
}

public static void main(String[] args) {
    MainFrame frame = new MainFrame();
    frame.setVisible(true);
    frame.setSize(600, 600);
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

这有效
    boardLabels[0] = new JLabel(pieces[1]);
    boardLabels[1] = new JLabel(pieces[1]);

当使用ImageIcons时,但是我想避免这种情况,因为要更新开发板,我将必须移除然后重新加载JLabel。我希望仅更新已经加载的标签。

编辑
我之前尝试过此方法,但它会引发空指针异常...
    boardLabels[0].setIcon(pieces[1]);
    boardLabels[1].setIcon(pieces[1]);

    boardPanel.add(boardLabels[0]);
    boardPanel.add(boardLabels[1]);

最佳答案

不要这样做,因为您不能向一个可视化容器中多次添加相同的组件。最好使用多个JLabel,但让它们使用相同的 ImageIcon 。 ImageIcons可以轻松使用一次以上:

public MainFrame() {
    pieceIcon[0] = new ImageIcon(System.getProperty("user.dir") +
        "/images/piece1.png");
    pieceIcon[1] = new ImageIcon(System.getProperty("user.dir") +
        "/images/piece2.png");

    this.add(boardPanel);
    displayGUIboard();
}


public void displayGUIboard() {
    boardPanel.add(new JLabel(pieceIcon[0]);
    boardPanel.add(new JLabel(pieceIcon[0]);
}

顺便说一句:请注意,所有变量都不应该是静态的。

编辑:关于您最近的编辑::


boardLabels[0] = new JLabel(pieces[1]);
boardLabels[1] = new JLabel(pieces[1]);



解决方案
不,您根本不需要更改JLabel。将JLabel保留在原处,而只需使用JLabel setIcon(...)方法交换它们所持有的图标。

编辑
另外,不要将变量与对象混淆。即使创建了一堆JLabel变量,即使它们全部都引用同一个JLabel对象,您仍然不能向容器中多次添加JLabel对象。

编辑您声明:



因此,创建一个使用GridLayout的JPanel并用不变的JLabel填充它。然后,只需根据int数组保存的值更改JLabel保存的图标。您可以创建一种简化和自动化该过程的方法。

编辑有关以下内容的:



然后像对待任何NPE一样解决此问题。找出引发NPE的行,检查该行上的变量,至少一个为null,然后对其进行修复,以便在尝试使用该变量之前对其进行初始化。

编辑
例如:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.image.BufferedImage;

import javax.swing.*;

@SuppressWarnings("serial")
public class GridExample extends JPanel {
   public static final int[][] MAP = {
      {1, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2},
      {1, 1, 0, 0, 2, 2, 2, 2, 2, 2, 2},
      {1, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2},
      {1, 1, 1, 0, 0, 2, 2, 2, 2, 2, 2},
      {1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 2},
      {1, 1, 1, 0, 0, 0, 2, 2, 2, 2, 2},
      {1, 1, 0, 0, 0, 2, 2, 2, 2, 2, 2},
      {1, 1, 1, 0, 0, 0, 2, 2, 2, 2, 2},
      {1, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2},
      {1, 1, 1, 1, 1, 0, 0, 0, 2, 2, 2},
      {1, 1, 1, 1, 1, 1, 0, 0, 0, 2, 2}
   };

   public static final Color[] COLORS = {};
   private JLabel[][] labelGrid = new JLabel[MAP.length][MAP[0].length];

   public GridExample() {
      setLayout(new GridLayout(MAP.length, MAP[0].length));
      for (int r = 0; r < labelGrid.length; r++) {
         for (int c = 0; c < labelGrid[r].length; c++) {
            labelGrid[r][c] = new JLabel();
            labelGrid[r][c].setIcon(Ground.getGround(MAP[r][c]).getIcon());
            add(labelGrid[r][c]);
         }
      }
   }

   private static void createAndShowGui() {
      GridExample mainPanel = new GridExample();

      JFrame frame = new JFrame("GridExample");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

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

enum Ground {
   DIRT(0, new Color(205,133, 63)), GRASS(1, new Color(0, 107, 60)),
   WATER(2, new Color(29, 172, 214));
   private int value;
   private Color color;
   private Icon icon;

   private Ground(int value, Color color) {
      this.value = value;
      this.color = color;

      icon = createIcon(color);
   }

   private Icon createIcon(Color color) {
      int width = 24; // how to use const in enum?
      BufferedImage img = new BufferedImage(width, width, BufferedImage.TYPE_INT_ARGB);
      Graphics g = img.getGraphics();
      g.setColor(color);
      g.fillRect(0, 0, width, width);
      g.dispose();
      return new ImageIcon(img);
   }

   public int getValue() {
      return value;
   }

   public Color getColor() {
      return color;
   }

   public Icon getIcon() {
      return icon;
   }

   public static Ground getGround(int value) {
      for (Ground ground : Ground.values()) {
         if (ground.getValue() == value) {
            return ground;
         }
      }
      return null;
   }

}

它显示了一个GUI网格:

关于java - JLabel图片数组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11553461/

10-13 01:19