我正在尝试将相同的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]);
答案 0 :(得分:11)
为了进行比较,我重新考虑了@ HFOE的example,以便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;
}
}
答案 1 :(得分:9)
不要这样做,因为您无法将多个相同的组件多次添加到可视化容器中。最好使用多个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]);
}
顺便说一句:请注意,变量的 none 应该是静态的。
关于您最近的修改修改:
这有效
boardLabels[0] = new JLabel(pieces[1]);
boardLabels[1] = new JLabel(pieces[1]);
使用ImageIcons时,但我想避免这种情况,因为要更新电路板,我必须删除然后重新加载JLabel。我更愿意只更新已加载的标签。“
<强>解决方案强>
不,你根本不需要改变JLabel。将JLabel保持原样,只需使用JLabel setIcon(...)
方法交换它们所持有的图标。
修改强>
另外,不要将变量与对象混淆。即使您创建了一堆JLabel变量,如果它们都引用相同的JLabel对象,您仍然无法将多个 JLabel对象多次添加到容器中。
修改您声明:
代码是游戏显示功能的一部分。整数数组将表示被解释的板(但不在上面的代码中),并且正确的Jlabel图像将被放置在gridlayout面板中以显示板的gui。我已经让显示代码工作正常,但在我当前的版本中,它从板上删除jlabel然后创建新的JLabel(片...)...但我更喜欢它从整数数组更新自己而不是删除标签,读取数组,然后重新创建标签。
因此,创建一个使用GridLayout并使用不变的JLabel填充它的JPanel。然后,只需根据int数组保存的值更改JLabels所拥有的图标。您可以创建一个简化和自动化此过程的方法。
编辑关于:
编辑我之前尝试过此操作,但它会抛出一个空指针异常。
然后像解决任何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网格: