Trifecta
Trifecta

Reputation: 67

How to put an image in a specific JPanel?

I am experimenting with board games lately and now I am making a Checkers board game. However I cannon figure out how to display a chip in a cell of the GridLayout. Each cell has it's own JPanel that I assigned in a 2D Array by a FOR Loop.

I need to display the image p1Chip which is just a .png in a specific JPanel, lets say it's variable name name is board[2][3], without messing up the GridLayout.

A sample code on how I can do this would be great as it will help me out understand better.

I have searched the internet but I can't find what I need, or at least something that explains how to do it.

Here is the code so far:

package checkers;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Image;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.io.File;
import java.io.IOException;
import javax.swing.JTextField;

public class Main extends JFrame {

    private JPanel contentPane;

    Image p1Chip;

    JPanel[][] board = new JPanel[8][8];



    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Main frame = new Main();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public Main() throws IOException {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 800, 800);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        startGame();
    }


    //Start Game!
        public void startGame() throws IOException{
            drawBoard();
        }

//******************************DRAWS BOARD******************************\\

 //Draws the board
    public void drawBoard() throws IOException{

        System.out.println("Start Drawing Board!");

        getContentPane().setLayout(new GridLayout(8,8));

        int colorAssignRow = 0; 
        int colorAssignCol = 0;

        for(int r = 0; r < 8; r++){

            colorAssignRow++;
            colorAssignCol = 0;

            for(int c = 0; c < 8; c++){

                colorAssignCol++;

                board[r][c] = new JPanel();


                if(colorAssignRow%2!=0){
                    if(colorAssignCol%2==0)board[r][c].setBackground(Color.RED);
                        else board[r][c].setBackground(Color.BLACK);
                }
                else if(colorAssignRow%2==0){
                    if(colorAssignCol%2==0)board[r][c].setBackground(Color.BLACK);
                    else board[r][c].setBackground(Color.RED);
                }

                getContentPane().add(board[r][c]);
            }

        }

        System.out.println("Board Drawing Done!");


    }

//******************************END OF DRAWING BOARD******************************\\

    public void getAssets(){
        System.out.println("Getting assets!");
        p1Chip = new ImageIcon("P1ChipNormal.png").getImage();
    }

}

The code above works fine as it just outputs the Checkers board of JPanels, each in a different cell of the grid.

UPDATE: This method is added to display the chips, however when I run this method, no chips show up.

 public void drawChips(){


    /*
     * When:    0 and even
     *          1 and odd
     *          2 and even
     */

    //Drawing Player One Chips\\
    for(int r = 0; r < 8; r++){ 
        for(int c = 0; c < 8; c++){

            label[r][c] = new JLabel();
            board[r][c] = new JPanel();

            if(r==0 && c%2==0){
                label[r][c].setIcon(p1Chip);
                board[r][c].add(label[r][c]);
            }
            else if(r==1 && c%2!=0 && c!=0){
                label[r][c].setIcon(p1Chip);
                board[r][c].add(label[r][c]);
            }
            else if(r==2 && c%2==0){
                label[r][c].setIcon(p1Chip);
                board[r][c].add(label[r][c]);
            }

    }   
    }   
}

Upvotes: 2

Views: 950

Answers (2)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285405

To show a chip in a JPanel cell:

  • Put the chip image into an ImageIcon
  • Put that ImageIcon into a JLabel via JLabel's setIcon(chipIcon) method
  • Add the JLabel to the JPanel via the add(someLabel) method -- and the JPanel now will display the image.

Then if you want to click and move the chip,

  • give it MouseListener and MouseMotionListener (MouseAdapater)
  • When clicked, remove the JLabel from its containing JPanel and elevate it to the top level window's glass pane.
  • Move it with the MouseAdapter.
  • When released, place the JLabel the JPanel that the mouse is over.

Upvotes: 4

An SO User
An SO User

Reputation: 24998

  1. Set the size, manually, of each of the JPanel in the board to be as large as the image plus some padding if you choose.
  2. Maintain a 2d array containing your JPanels.
  3. Call repaint() on your JPanels whenever the user clicks on it. Do not forget to overrride the paintComponent() where you draw the image onto the JPanel

Here is how you might do the painting of image:

JPanel onePanel = new JPanel(){
                                @Override
                                public void paintComponent(Graphics g){
                                    super.paintComponent(g);
                                    g.drawImage(image,0,0,null);
                                }
                            }    

In the snippet above, I have created a custom JPanel so as to suit the needs.

So, lets say the user clicks on the first JPanel which is on position (0 , 0). You retrieve the JPanel from the board[][] and call repaint() on it. This will result in the image being drawn.

Upvotes: 1

Related Questions