Array di immagini JLabel

Sto provando a caricare due volte la stessa immagine memorizzata in jlabel in un pannello di griglia, ma invece di creare due istanze dell’immagine, l’immagine viene visualizzata solo una volta e poi spostata.

Come posso memorizzare la stessa posizione di JLabel nell’array di pezzi in più di una JLabel nell’array boardLabels.

Grazie 🙂

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

Questo funziona

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

quando si usano ImageIcons, ma voglio evitare questo dato che per aggiornare la scheda dovrò rimuovere quindi ricaricare i JLabels. Preferirei semplicemente aggiornare le etichette già caricate.

modifica Ho provato prima, ma genera un’eccezione di puntatore nullo …

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

Non farlo poiché non è ansible aggiungere lo stesso componente più di una volta a un contenitore visualizzato. Meglio usare più JLabels ma farli usare lo stesso ImageIcon . ImageIcons può essere utilizzato più volte con facilità:

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

Per inciso: nota che nessuna delle tue variabili dovrebbe essere statica.

Modifica: per quanto riguarda la modifica recente:

Questo funziona

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

quando si usano ImageIcons, ma voglio evitare questo dato che per aggiornare la scheda dovrò rimuovere quindi ricaricare i JLabels. Preferirei semplicemente aggiornare le etichette già caricate. ”

Soluzione
No, non devi assolutamente cambiare JLabels. Mantieni i tuoi JLabel dove sono, ma semplicemente scambia le icone che contengono usando il metodo setIcon(...) .

modificare
Inoltre, non confondere le variabili con gli oggetti. Anche se si creano un gruppo di variabili JLabel, se si riferiscono tutti allo stesso object JLabel, non è ancora ansible aggiungere un object JLabel più di una volta a un contenitore.

Modifica dichiari:

Il codice fa parte della funzione di visualizzazione di un gioco. Un array di numeri interi rappresenterà la scheda che viene interpretata (ma non nel codice precedente) e le immagini Jlabel corrette verranno posizionate in un pannello di gridlayout per visualizzare la GUI della scheda. Ho ottenuto il codice di visualizzazione per funzionare bene, ma nella mia versione attuale rimuove i jlabels dalla scheda quindi crea nuovi JLabels (pezzo …) … ma preferirei aggiornarsi dalla matrice di interi piuttosto che rimuovere le etichette, leggendo l’array, quindi ricreando le etichette.

Quindi crea un JPanel che usi GridLayout e riempilo con JLabels immutabili. Quindi modifica semplicemente le icone contenute in JLabels in base ai valori contenuti nell’array int. È ansible creare un metodo che semplifica e automatizza questo processo.

Modifica riguardante:

modifica Ho provato prima, ma genera un’eccezione di puntatore nullo.

Allora risolvi questo come faresti con qualsiasi NPE. Scopri quale linea lancia l’NPE, controlla le variabili sulla linea, almeno una è nullo, quindi correggila in modo da inizializzare la variabile prima di provare ad usarla.

modificare
per esempio:

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

Che mostra una griglia GUI:
inserisci la descrizione dell'immagine qui

Per fare un confronto, ho ri-fattorizzato l’ esempio di HFOE in modo che Ground implements Icon e indicizzi l’array restituito da values() . Poiché value è un dettaglio di implementazione, int[][] MAP potrebbe invece essere Ground[][] MAP .

Aggiornamento: questa variante illustra Ground[][] MAP e aggiunge TexturePaint .

inserisci la descrizione dell'immagine qui

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