JLabel图像数组

我试图加载相同的jlabel存储的图像两次到一个网格布局面板,但不是创build图像的两个实例,图像只显示一次,然后移动。

如何将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") + "http://img.dovov.compiece1.png")); pieces[1] = new JLabel(new ImageIcon(System.getProperty("user.dir") + "http://img.dovov.compiece2.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,但我想避免这一点,因为更新板,我将不得不删除然后重新加载JLabels。 我宁愿只更新已经加载的标签。

编辑我以前试过,但它会抛出一个空指针exception…

  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") + "http://img.dovov.compiece1.png"); pieceIcon[1] = new ImageIcon(System.getProperty("user.dir") + "http://img.dovov.compiece2.png"); this.add(boardPanel); displayGUIboard(); } public void displayGUIboard() { boardPanel.add(new JLabel(pieceIcon[0]); boardPanel.add(new JLabel(pieceIcon[0]); } 

顺便说一下:请注意,您的任何variables都不应该是静态的。

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

这工作

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

当使用ImageIcons,但我想避免这一点,因为更新板,我将不得不删除然后重新加载JLabels。 我宁愿只更新已经加载的标签。“


不,你根本不需要改变JLabels。 保持JLabel的位置,只需使用JLabel setIcon(...)方法交换它们所保存的图标即可。

编辑
另外,不要将variables与对象混淆。 即使您创build了一堆JLabelvariables,但如果它们都引用同一个JLabel对象,您仍然不能多次向容器添加JLabel对象

编辑你的状态:

代码是游戏显示function的一部分。 一个整数数组将代表被解释的板(但不是在上面的代码中),正确的Jlabel图像将被放置到一个网格布局面板中以显示该板的gui。 我已经得到了显示代码工作正常,但在我目前的版本,它从板上删除jlabels然后创build新的JLabels(片…)…但我更喜欢它更新自己的整数数组而不是标签,读取数组,然后重新创build标签。

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

编辑关于:

编辑我以前试过,但它会引发空指针exception。

然后解决这个问题,就像任何NPE一样。 找出哪一行引发NPE,检查行上的variables,至less有一个是null,然后修复它,以便在尝试使用它之前初始化variables。

编辑
例如:

 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网格:
在这里输入图像描述

为了比较,我重新考虑了@HFOOE的例子,以便Ground implements Icon并索引由values()返回的数组。 由于value是一个实现细节, int[][] MAP可以改为Ground[][] MAP

更新:这个变化说明了Ground[][] MAP并添加了TexturePaint

在这里输入图像描述

 import java.awt.Color; import java.awt.Component; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridLayout; import java.awt.TexturePaint; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.util.Random; import javax.swing.*; /** @see https://stackoverflow.com/a/11556441/230513 */ public class GridExample extends JPanel { public static final Ground[][] MAP = { {Ground.GRASS, Ground.GRASS, Ground.DIRT, Ground.WATER, Ground.WATER}, {Ground.GRASS, Ground.DIRT, Ground.CITY, Ground.WATER, Ground.WATER}, {Ground.GRASS, Ground.DIRT, Ground.CITY, Ground.WATER, Ground.WATER}, {Ground.GRASS, Ground.DIRT, Ground.DIRT, Ground.DIRT, Ground.WATER}, {Ground.GRASS, Ground.GRASS, Ground.DIRT, Ground.WATER, Ground.WATER}, }; 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(MAP[r][c]); add(labelGrid[r][c]); } } } private static void createAndShowGui() { GridExample mainPanel = new GridExample(); JFrame frame = new JFrame("GridExample"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(mainPanel); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { createAndShowGui(); } }); } } enum Ground implements Icon { DIRT(new Color(205, 133, 63)), GRASS(new Color(0, 107, 60)), WATER(new Color(29, 172, 214)), CITY(Color.lightGray); private static final int SIZE = 42; private Random random = new Random(); private TexturePaint paint; private Ground(Color color) { this.paint = initPaint(color); } private TexturePaint initPaint(Color color) { BufferedImage image = new BufferedImage( SIZE, SIZE, BufferedImage.TYPE_INT_ARGB); Rectangle2D.Double rect = new Rectangle2D.Double(0, 0, SIZE, SIZE); for (int row = 0; row < SIZE; row++) { for (int col = 0; col < SIZE; col++) { if (random.nextBoolean()) { image.setRGB(col, row, color.getRGB()); } else { if (random.nextBoolean()) { image.setRGB(col, row, color.darker().getRGB()); } else { image.setRGB(col, row, color.brighter().getRGB()); } } } } return new TexturePaint(image, rect); } @Override public void paintIcon(Component c, Graphics g, int x, int y) { Graphics2D g2d = (Graphics2D) g; g2d.setPaint(paint); g.fillRect(0, 0, SIZE, SIZE); } @Override public int getIconWidth() { return SIZE; } @Override public int getIconHeight() { return SIZE; } }