I have been studying Java from the past one week and thought of implementing a simple memory game in which the computer first shows a set of images with images repeated, then closes all of them after some time. Then the user has to select the tiles where the same images were shown. To load images from my images/ folder and display, i ve written the following code.
Board.java
import java.awt.GridLayout;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.stream.*;
import java.nio.file.*;
import java.nio.*;
import java.io.*;
import java.util.*;
class Board extends JPanel{
//make tile part of the board
private class Tile extends JLabel{
private String icon_path;
public Tile(ImageIcon icon, String icon_path){
super(icon);
this.icon_path = icon_path;
}
public String getIconPath(){
return icon_path;
}
}
private int num_rows=4;
private int num_columns = 2;
private boolean playable = true; //playable tells us whether the board is playable, true means game not over
private List<Tile> tiles = new LinkedList<Tile>();
public boolean isPlayable(){
return playable;
}
public Board(int rows, int columns){
this();
this.num_rows = rows;
this.num_columns = columns;
}
public Board(){
setLayout(new GridLayout(num_rows, num_columns));
fillBoard();
}
private void fillBoard(){
List<Path> image_paths = null;
try(Stream<Path> paths = Files.list(Paths.get("images"))){
image_paths = paths.collect(Collectors.toList());
}
catch(IOException e){
e.printStackTrace();
}
// Tile temp_tile = null;
for(Path p: image_paths){
try {
BufferedImage img = ImageIO.read(new File(p.toString()));
Tile temp_tile1 = new Tile(new ImageIcon(img), p.toString());
Tile temp_tile2 = new Tile(new ImageIcon(img), p.toString());
tiles.add(temp_tile1);
// add(temp_tile);
tiles.add(temp_tile2);
// add(temp_tile);
// tiles.add(new Tile(new ImageIcon(img), p.toString()));
// tiles.add(new Tile(new ImageIcon(img), p.toString()));
// tiles.add(temp_tile);
// add(temp_tile);
// add(new Tile(new ImageIcon(img), p.toString()));
// add(new Tile(new ImageIcon(img), p.toString()));
// add(temp_tile);
}
catch (IOException e) {
e.printStackTrace();
}
}//end of for loop
for(Tile t: tiles){
add(t);
}
}// end of fill board
}
MemoryGame.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.BorderLayout;
public class MemoryGame{
private JFrame mainPanel = new JFrame("Memory Game");
private Board board = new Board(4,2);
public MemoryGame(){
mainPanel.setLayout(new BorderLayout());
mainPanel.add(board, BorderLayout.CENTER);
mainPanel.setSize(800,800);
mainPanel.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainPanel.pack();
mainPanel.setVisible(true);
}
public static void main(String[] args) {
new MemoryGame();
}
}
this is doing the job. ie loading images in 4x2 grid. Now the actual code in the foreach loop of Board.java was like this:
for(Path p: image_paths){
try {
BufferedImage img = ImageIO.read(new File(p.toString()));
Tile temp_tile = new Tile(new ImageIcon(img), p.toString());
tiles.add(temp_tile);
add(temp_tile);
tiles.add(temp_tile);
add(temp_tile);
catch (IOException e) {
e.printStackTrace();
}
}//end of for loop
}// end of fill board
}
with this version although i ve call add method of panel twice(to create two tiles with same icon) the replicate image is not loaded and i get 4x1 grid. Is java treating the item insertion to JPanel as if it were a set? Can someone explain what is happening here? Also is there a better way to do this operation?