不要这样做,因为你不能将同一组件添加到可视化容器中超过一次。最好使用多个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])
当使用ImageIcons时,我想避免这种情况,因为要更新面板,必须先删除再重新加载JLabels。我更喜欢只更新已经加载的标签。
解决方案
实际上你根本不需要改变JLabels。保留你的JLabels不变,但使用JLabel的
setIcon(...)
方法来交换它们所持有的图标即可。
编辑
此外,不要将变量与对象混淆。即使您创建了一堆JLabel变量,如果它们都引用同一个JLabel对象,仍然无法将一个
JLabel对象添加多次到容器中。
编辑
你说:
该代码是游戏显示函数的一部分。整型数组将表示解释后的棋盘,并将正确的JLabel图像放入网格布局面板中以显示棋盘的GUI。我已经成功地让显示代码工作,但在我的当前版本中,它会从面板中删除jlabels然后创建新的JLabels(piece...)……但我更希望它能够从整数数组中自动更新而不是删除标签、读取数组、然后重新创建标签。
那么,创建一个使用GridLayout的JPanel并填充它不变的JLabels。然后根据int数组中保存的值更改JLabel所持有的图标。您可以创建一个简化和自动化此过程的方法。
编辑 关于:
我之前尝试过这个方法,但它会抛出空指针异常。
那么像解决任何NPE一样解决它。找出哪行代码引发了NPE,检查该行的变量,至少一个为空,然后修复它,以便在尝试使用变量之前初始化它。
编辑
例如:
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;
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网格的界面:
![输入图像描述](https://istack.dev59.com/gGNtj.webp)
user.dir
路径获取应用程序资源非常脆弱。由于这些图像显然是应用程序固有的,因此应将它们作为嵌入式资源添加到Jar中。 - Andrew Thompson