I am building a GUI for a maze-based game.
The main JPanel is made up of smaller JPanels I call Tiles. My goal is to have a specific tile JPanel be highlighted when the player is in that cell. It would look something like this:
Here is the code for an MRE. I think you can use any 3 test.png with it. I think its not working because the JLabel with the image on it is covering up the highlight.
public class testGui extends JFrame {
private final Board board;
public testGui() {
this.setSize(600, 600);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.board = new Board();
JScrollPane scroller = new JScrollPane(board);
this.add(scroller, BorderLayout.CENTER);
}
public ImageIcon getImage(int i) {
try {
BufferedImage imageBase = ImageIO.read(getClass().getResource(String.format("/images/test%d.png", i)));
int width = imageBase.getWidth();
int height = imageBase.getHeight();
BufferedImage combined = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics g = combined.getGraphics();
g.drawImage(imageBase, 0, 0, null);
ImageIcon icon = new ImageIcon(combined);
return icon;
} catch (IOException ex) {
Logger.getLogger(DungeonGui.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
private class Board extends JPanel {
public Board() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
for (int i = 0; i < 3; i ) {
Tile tile = new Tile(i);
cellPanel.setName(String.format("%d", i));
add(tile, gbc);
gbc.gridx ;
if (gbc.gridx >= 3) {
gbc.gridx = 0;
gbc.gridy ;
}
if (i ==2) {
//TODO highlight JUST this tile
}
}
}
private class Tile extends JPanel {
private int i;
private JLabel label;
private Color highlight = new Color(0, 0, 255, 128);
public CellPanel(int i) {
super();
this.i = i;
this.setLayout(new GridLayout(1, 1));
ImageIcon imageIcon = getImage(i);
this.label = new JLabel(imageIcon);
this.add(label);
setOpaque(false);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
ImageIcon imageIcon = getImage(i);
this.label.setIcon(imageIcon);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(highlight);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.dispose();
}
}
@Override
public void refresh() {
this.repaint();
}
@Override
public void makeVisible() {
this.setVisible(true);
}
}
CodePudding user response:
Never update the state of component from within a paint
method, this is going to cause no end of issues for you in the long run.
If you want more control over the image, then you might consider creating a custom component capable of painting the image and then performing what ever overlay/highlights you want, for example
public class CellPane extends JPanel {
private BufferedImage image;
private boolean highlighted;
public CellPane(BufferedImage image) {
this.image = image;
}
@Override
public Dimension getPreferredSize() {
BufferedImage image = getImage();
return image == null ? new Dimension(128, 128) : new Dimension(image.getWidth(), image.getHeight());
}
public boolean isHighlighted() {
return highlighted;
}
public void setHighlighted(boolean highlighted) {
this.highlighted = highlighted;
repaint();
}
public BufferedImage getImage() {
return image;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.drawImage(image, 0, 0, this);
if (isHighlighted()) {
g2d.setColor(new Color(0, 0, 255, 128));
g2d.fillRect(0, 0, getWidth(), getHeight());
}
g2d.dispose();
}
}
Runnable example
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
List<Maze.Direction> directions = new ArrayList<>(32);
directions.add(Maze.Direction.EAST_SOUTH);
directions.add(Maze.Direction.EAST_SOUTH_WEST);
directions.add(Maze.Direction.EAST_SOUTH_WEST);
directions.add(Maze.Direction.EAST_SOUTH_WEST);
directions.add(Maze.Direction.EAST_SOUTH_WEST);
directions.add(Maze.Direction.SOUTH_WEST);
directions.add(Maze.Direction.NORTH_EAST_SOUTH);
directions.add(Maze.Direction.NORTH_EAST_SOUTH_WEST);
directions.add(Maze.Direction.NORTH_EAST_SOUTH_WEST);
directions.add(Maze.Direction.NORTH_EAST_SOUTH_WEST);
directions.add(Maze.Direction.NORTH_EAST_SOUTH_WEST);
directions.add(Maze.Direction.NORTH_SOUTH_WEST);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH);
directions.add(Maze.Direction.NORTH);
directions.add(Maze.Direction.NORTH);
directions.add(Maze.Direction.NORTH);
directions.add(Maze.Direction.NORTH);
directions.add(Maze.Direction.NORTH);
System.out.println(directions.size());
Maze maze = new DefaultMaze(5, 6, directions);
MazeGui frame = new MazeGui(maze);
frame.addClickListener(null);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public interface Maze {
enum Direction {
EAST_SOUTH("EastSouth.png"), EAST_SOUTH_WEST("EastSouthWest.png"), SOUTH_WEST("SouthWest.png"),
NORTH_EAST_SOUTH("NorthEastSouth.png"), NORTH_EAST_SOUTH_WEST("NorthEastSouthWest.png"),
NORTH_SOUTH_WEST("NorthSouthWest.png"), NORTH_SOUTH("NorthSouth.png"), NORTH("North.png");
private BufferedImage image;
private Direction(String name) {
try {
image = ImageIO.read(getClass().getResource("/images/" name));
} catch (IOException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
public BufferedImage getImage() {
return image;
}
}
public int getRows();
public int getColumns();
public Direction getRoomDirections(int index);
}
public class DefaultMaze implements Maze {
int rows;
int columns;
private List<Direction> directions;
public DefaultMaze(int rows, int columns, List<Direction> directions) {
this.rows = rows;
this.columns = columns;
this.directions = directions;
}
public int getRows() {
return rows;
}
public int getColumns() {
return columns;
}
@Override
public Direction getRoomDirections(int index) {
return directions.get(index);
}
}
// Missing code
public interface DungeonController {
}
public class MazeGui extends JFrame {
private final Board board;
public MazeGui(Maze m) {
this.setSize(600, 600);
this.setResizable(false);
this.board = new Board(m);
JScrollPane scroller = new JScrollPane(board);
this.add(scroller, BorderLayout.CENTER);
setTitle("Dungeon Escape");
}
public Board getBoard() {
return board;
}
public void addClickListener(DungeonController listener) {
Board board = getBoard();
board.addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
board.highlightCellAt(e.getPoint());
}
});
}
private class Board extends JPanel {
private Maze maze;
private CellPane lastHighlightedCell = null;
public Board(Maze maze) {
this.maze = maze;
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
for (int index = 0; index < maze.getRows() * maze.getColumns(); index ) {
Maze.Direction direction = maze.getRoomDirections(index);
// Could use direction directly
CellPane cellPane = new CellPane(direction.getImage());
cellPane.setName(direction.name());
add(cellPane, gbc);
gbc.gridx ;
if (gbc.gridx >= maze.getColumns()) {
gbc.gridx = 0;
gbc.gridy ;
}
}
}
public void highlightCellAt(Point p) {
Component component = getComponentAt(p);
if (component instanceof CellPane) {
CellPane cell = (CellPane) component;
cell.setHighlighted(true);
if (lastHighlightedCell != null && cell != lastHighlightedCell) {
lastHighlightedCell.setHighlighted(false);
}
lastHighlightedCell = cell;
}
}
}
}
public class CellPane extends JPanel {
private BufferedImage image;
private boolean highlighted;
public CellPane(BufferedImage image) {
this.image = image;
}
@Override
public Dimension getPreferredSize() {
BufferedImage image = getImage();
return image == null ? new Dimension(128, 128) : new Dimension(image.getWidth(), image.getHeight());
}
public boolean isHighlighted() {
return highlighted;
}
public void setHighlighted(boolean highlighted) {
this.highlighted = highlighted;
repaint();
}
public BufferedImage getImage() {
return image;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.drawImage(image, 0, 0, this);
if (isHighlighted()) {
g2d.setColor(new Color(0, 0, 255, 128));
g2d.fillRect(0, 0, getWidth(), getHeight());
}
g2d.dispose();
}
}
}
Another approach...
Another approach might to take advantage of GridBagLayout
. You can get the constraints used to layout out a given component and then re-use them to apply a "overlay" panel to the same location.
This means you can keep the JLabel
for displaying the maze direction and use a "overlay" component to provide different highlights
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
List<Maze.Direction> directions = new ArrayList<>(32);
directions.add(Maze.Direction.EAST_SOUTH);
directions.add(Maze.Direction.EAST_SOUTH_WEST);
directions.add(Maze.Direction.EAST_SOUTH_WEST);
directions.add(Maze.Direction.EAST_SOUTH_WEST);
directions.add(Maze.Direction.EAST_SOUTH_WEST);
directions.add(Maze.Direction.SOUTH_WEST);
directions.add(Maze.Direction.NORTH_EAST_SOUTH);
directions.add(Maze.Direction.NORTH_EAST_SOUTH_WEST);
directions.add(Maze.Direction.NORTH_EAST_SOUTH_WEST);
directions.add(Maze.Direction.NORTH_EAST_SOUTH_WEST);
directions.add(Maze.Direction.NORTH_EAST_SOUTH_WEST);
directions.add(Maze.Direction.NORTH_SOUTH_WEST);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH_SOUTH);
directions.add(Maze.Direction.NORTH);
directions.add(Maze.Direction.NORTH);
directions.add(Maze.Direction.NORTH);
directions.add(Maze.Direction.NORTH);
directions.add(Maze.Direction.NORTH);
directions.add(Maze.Direction.NORTH);
System.out.println(directions.size());
Maze maze = new DefaultMaze(5, 6, directions);
MazeGui frame = new MazeGui(maze);
frame.addClickListener(null);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public interface Maze {
enum Direction {
EAST_SOUTH("EastSouth.png"), EAST_SOUTH_WEST("EastSouthWest.png"), SOUTH_WEST("SouthWest.png"),
NORTH_EAST_SOUTH("NorthEastSouth.png"), NORTH_EAST_SOUTH_WEST("NorthEastSouthWest.png"),
NORTH_SOUTH_WEST("NorthSouthWest.png"), NORTH_SOUTH("NorthSouth.png"), NORTH("North.png");
private BufferedImage image;
private Direction(String name) {
try {
image = ImageIO.read(getClass().getResource("/images/" name));
} catch (IOException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
public BufferedImage getImage() {
return image;
}
}
public int getRows();
public int getColumns();
public Direction getRoomDirections(int index);
}
public class DefaultMaze implements Maze {
int rows;
int columns;
private List<Direction> directions;
public DefaultMaze(int rows, int columns, List<Direction> directions) {
this.rows = rows;
this.columns = columns;
this.directions = directions;
}
public int getRows() {
return rows;
}
public int getColumns() {
return columns;
}
@Override
public Direction getRoomDirections(int index) {
return directions.get(index);
}
}
// Missing code
public interface DungeonController {
}
public class MazeGui extends JFrame {
// Missing code
public interface DungeonController {
}
private final Board board;
public MazeGui(Maze m) {
this.setSize(600, 600);
this.setResizable(false);
this.board = new Board(m);
JScrollPane scroller = new JScrollPane(board);
this.add(scroller, BorderLayout.CENTER);
setTitle("Dungeon Escape");
}
public Board getBoard() {
return board;
}
public void addClickListener(DungeonController listener) {
Board board = getBoard();
board.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
board.highlightCellAt(e.getPoint());
}
});
}
private class Board extends JPanel {
private Maze maze;
private HighlighPane highlightPane = new HighlighPane();
public Board(Maze maze) {
this.maze = maze;
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
for (int index = 0; index < maze.getRows() * maze.getColumns(); index ) {
Maze.Direction direction = maze.getRoomDirections(index);
JLabel label = new JLabel(new ImageIcon(direction.getImage()));
label.setName(direction.name());
add(label, gbc);
gbc.gridx ;
if (gbc.gridx >= maze.getColumns()) {
gbc.gridx = 0;
gbc.gridy ;
}
}
}
public void highlightCellAt(Point point) {
Component component = getComponentAt(point);
remove(highlightPane);
if (component != null) {
GridBagLayout layout = (GridBagLayout) getLayout();
GridBagConstraints gbc = layout.getConstraints(component);
gbc.fill = gbc.BOTH;
add(highlightPane, gbc, 0);
}
revalidate();
repaint();
}
}
}
public class HighlighPane extends JPanel {
private Color highlight = new Color(0, 0, 255, 128);
public HighlighPane() {
setOpaque(false);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(highlight);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.dispose();
}
}
}
Modification of "MCVE"
The is, yet, another modification of your code. This highlights to me that you've not taken the time to read through Performing Custom Painting, especially A Closer Look at the Paint Mechanism, which highlights the order in which paint methods are chained together.
Basically paint
paintComponent
paintBorder
paintChildren
What's important to note here is, paintComponent
is called FIRST, before any child components are painted. You also need to beware that it's entirely possible for a child component to under go a paint pass without the parent component been involved.
Sooo, when designing "highlight" or "overlay" solutions, you need to keep this is mind, which is why the first suggestion was to do away with JLabel
and do it all yourself.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import stackoverflow.Test.ReadOnlyModel;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
List<List<String>> directions = new ArrayList<>(32);
List<String> row = new ArrayList<>();
row.add("EastSouth");
row.add("EastSouthWest");
row.add("EastSouthWest");
row.add("EastSouthWest");
row.add("EastSouthWest");
row.add("SouthWest");
directions.add(row);
row = new ArrayList<>();
row.add("NorthEastSouth");
row.add("NorthEastSouthWest");
row.add("NorthEastSouthWest");
row.add("NorthEastSouthWest");
row.add("NorthEastSouthWest");
row.add("NorthSouthWest");
directions.add(row);
row = new ArrayList<>();
row.add("NorthSouth");
row.add("NorthSouth");
row.add("NorthSouth");
row.add("NorthSouth");
row.add("NorthSouth");
row.add("NorthSouth");
directions.add(row);
row = new ArrayList<>();
row.add("NorthSouth");
row.add("NorthSouth");
row.add("NorthSouth");
row.add("NorthSouth");
row.add("NorthSouth");
row.add("NorthSouth");
directions.add(row);
row = new ArrayList<>();
row.add("North");
row.add("North");
row.add("North");
row.add("North");
row.add("North");
row.add("North");
directions.add(row);
System.out.println(directions.size());
DefaultModel maze = new DefaultModel(5, 6, directions);
TestGUI frame = new TestGUI(maze);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public interface ReadOnlyModel {
public int getRows();
public int getColumns();
public String getDirectionAt(int row, int column);
public Image getImageFor(String direction);
}
public class DefaultModel implements ReadOnlyModel {
int rows;
int columns;
private List<List<String>> directions;
public DefaultModel(int rows, int columns, List<List<String>> directions) {
this.rows = rows;
this.columns = columns;
this.directions = directions;
}
public int getRows() {
return rows;
}
public int getColumns() {
return columns;
}
@Override
public String getDirectionAt(int row, int column) {
return directions.get(row).get(column);
}
@Override
public Image getImageFor(String direction) {
try {
return ImageIO.read(getClass().getResource(String.format("/images/%s.png", direction)));
} catch (IOException ex) {
System.out.println(direction);
ex.printStackTrace();
}
return null;
}
}
public class TestGUI extends JFrame {
private final Board board;
public TestGUI(ReadOnlyModel m) {
this.setSize(600, 600);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.board = new Board(m);
JScrollPane scroller = new JScrollPane(board);
this.add(scroller, BorderLayout.CENTER);
}
private class Board extends JPanel {
public Board(ReadOnlyModel m) {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
int counter = 0;
for (int row = 0; row < m.getRows(); row ) {
for (int col = 0; col < m.getColumns(); col ) {
String direction = m.getDirectionAt(row, col);
Image image = m.getImageFor(direction);
Tile tile = new Tile(direction, image);
add(tile, gbc);
gbc.gridx ;
counter ;
if (counter % 2 == 0) {
tile.setHighlighted(true);
}
}
counter ;
gbc.gridx = 0;
gbc.gridy ;
}
}
private class Tile extends JPanel {
private String direction;
private Color highlight = new Color(0, 0, 255, 128);
private Image image;
private boolean highlighted = false;
public Tile(String direction, Image image) {
this.direction = direction;
setName(direction);
setOpaque(false);
this.image = image;
}
@Override
public Dimension getPreferredSize() {
Image image = getImage();
return image == null ? new Dimension(128, 128) : new Dimension(image.getWidth(this), image.getHeight(this));
}
public void setHighlighted(boolean highlighted) {
this.highlighted = highlighted;
}
public boolean isHighlighted() {
return highlighted;
}
public Image getImage() {
return image;
}
public Color getHighlight() {
return highlight;
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
Image image = getImage();
if (image != null) {
g2d.drawImage(image, 0, 0, this);
}
if (isHighlighted()) {
g2d.setColor(highlight);
g2d.fillRect(0, 0, getWidth(), getHeight());
}
g2d.dispose();
}
}
// @Override
// public void refresh() {
//
// this.repaint();
// }
//
// @Override
// public void makeVisible() {
//
// this.setVisible(true);
//
// }
}
}
}
CodePudding user response:
I figured it out! The key was putting the highlighting code (and logic) in the getImage method where the images are drawn on the graphic.
Here is the code. Check the getImage method:
public class testGui extends JFrame {
private final Board board;
public testGui() {
this.setSize(600, 600);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.board = new Board();
JScrollPane scroller = new JScrollPane(board);
this.add(scroller, BorderLayout.CENTER);
}
public ImageIcon getImage(int i) {
try {
BufferedImage imageBase = ImageIO.read(getClass().getResource(String.format("/images/test%d.png", i)));
int width = imageBase.getWidth();
int height = imageBase.getHeight();
BufferedImage combined = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics g1 = combined.getGraphics();
Graphics2D g = (Graphics2D) g1.create();
g.drawImage(imageBase, 0, 0, null);
if (i ==2) {
g.setColor(new Color(0, 0, 255, 128));
g.fillRect(0, 0, getWidth(), getHeight());
g.dispose();
}
ImageIcon icon = new ImageIcon(combined);
return icon;
} catch (IOException ex) {
Logger.getLogger(DungeonGui.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
private class Board extends JPanel {
public Board() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
for (int i = 0; i < 3; i ) {
Tile tile = new Tile(i);
cellPanel.setName(String.format("%d", i));
add(tile, gbc);
gbc.gridx ;
if (gbc.gridx >= 3) {
gbc.gridx = 0;
gbc.gridy ;
}
}
}
private class Tile extends JPanel {
private int i;
private JLabel label;
public CellPanel(int i) {
super();
this.i = i;
this.setLayout(new GridLayout(1, 1));
ImageIcon imageIcon = getImage(i);
this.label = new JLabel(imageIcon);
this.add(label);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
ImageIcon imageIcon = getImage(i);
this.label.setIcon(imageIcon);
}
}
@Override
public void refresh() {
this.repaint();
}
@Override
public void makeVisible() {
this.setVisible(true);
}
}