Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
65 views
in Technique[技术] by (71.8m points)

java - JLabel images array

I am trying to load the same jlabel stored image twice into a gridlayout panel, however instead of creating two instances of the image, the image is only displayed once then moved.

How can I store the same JLabel position in the pieces array into more than one JLabel in the boardLabels array.

Thanks :)

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

This works

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

when using ImageIcons, but I want to avoid this since to update the board I will have to remove then reload the JLabels. I would prefer to just update the already loaded labels.

edit I tried this before but it throws a null pointer exception...

    boardLabels[0].setIcon(pieces[1]);
    boardLabels[1].setIcon(pieces[1]);

    boardPanel.add(boardLabels[0]);
    boardPanel.add(boardLabels[1]);
Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

For comparison, I've re-factored @HFOE's example so that Ground implements Icon and indexes the array returned by values(). As value is an implementation detail, int[][] MAP could instead be Ground[][] MAP.

Update: This variation illustrates Ground[][] MAP and adds TexturePaint.

enter image description here

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;
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...