• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 440
  • Last Modified:

Overlapping BufferedImages

Hi,

I am trying to create a card game with overlapping cards. Each card is created as a BufferedImage in a class that extends a JPanel (ImagePanel). The ImagePanels are then used inside a JFrame. However, for each ImagePanel that is added to the JFrame, only the last one added appears on the content pane. Am I doing something wrong? I have a feeling its to do with the opacity of the component, but can't seem to figure it out. Any pointers in the right direction will be appreciated. I have added a simplified version of the code I am using to run this.

Thanks,
public class ImagePanel extends JPanel{
	int x,y;
	MainWindow mainWin;
	BufferedImage image;  
 
    public ImagePanel(String p, int x, int y, Color c) throws IOException{
        this.x=x;
        this.y=y;
        mainWin = win;
        String path = "src/images/"+p+".gif";
        image = ImageIO.read(new File(path));
        setSize(image.getWidth(), image.getHeight());
    }
 
    protected void paintComponent(Graphics g){
        super.paintComponent(g);
 
		g.drawImage(image, x, y, mainWin);
    }
 
}
 
public class MainWindow extends JFrame{
    
    ImagePanel img1,img2,img3 ;
    String cardPaths1,cardPaths2,cardPaths3 ;
 
	int x1 = 100;
	int y1 = 100;
	int x2 = 120;
	int y2 = 120;
	int x3 = 140;
	int y3 = 140;
 
 
    public MainWindow(){
		Dimension dimInitScreenSize = Toolkit.getDefaultToolkit().getScreenSize() ;
        int wndWidth = dimInitScreenSize.width*2/3 ;
        int wndHeight = dimInitScreenSize.height*2/3 ;
        setSize( wndWidth , wndHeight ) ;
 
        try {
            img1 = new ImagePanel(this, "a.gif",x1,y1,Color.green);
            img2 = new ImagePanel(this, "b.gif",x2,y2,Color.blue);
            img3 = new ImagePanel(this, "c.gif",x3,y3,Color.red);
        } catch (IOException ex) {
            Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        }
 
        getContentPane().add(img1);
        getContentPane().add(img2);
        getContentPane().add(img3);
 
        setVisible(true);
    }
}

Open in new window

0
mitzdadon
Asked:
mitzdadon
  • 7
  • 7
  • 3
1 Solution
 
ksivananthCommented:
because you laying the panels on top of one another,

        getContentPane().add(img1);
        getContentPane().add(img2);
        getContentPane().add(img3);

how do you want to displayit?
0
 
CEHJCommented:
Set a FlowLayout on your content pane of your frame
0
 
CEHJCommented:
e.g.
getContentPane().setLayout(new FlowLayout());
getContentPane().add(img1);
getContentPane().add(img2);
getContentPane().add(img3);

Open in new window

0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
mitzdadonAuthor Commented:
The cards should overlap each other, according to the x,y value. For clarity, I am attaching all the files required to run this code, and a screenshot of the output. If you create a main class/method and run, you should see the problem I am facing.

From here, you will notice that 2 of the cards are not being displayed at all, so setting a FlowLayout wont help.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;import javax.swing.JPanel;
;
 
public class MainWindow extends JFrame{
    
    ImagePanel img1,img2,img3 ;
    String cardPaths1,cardPaths2,cardPaths3 ;
    Rectangle imgFrame1,imgFrame2,imgFrame3;
 
    int x1 = 100;
    int y1 = 100;
    int x2 = 120;
    int y2 = 120;
    int x3 = 140;
    int y3 = 140;
    
    public MainWindow(){
		Dimension dimInitScreenSize = Toolkit.getDefaultToolkit().getScreenSize() ;
        int wndWidth = dimInitScreenSize.width*2/3 ;
        int wndHeight = dimInitScreenSize.height*2/3 ;
        setSize( wndWidth , wndHeight ) ;
 
        cardPaths1 = new String("5h");
        cardPaths2 = new String("2c");
        cardPaths3 = new String("8d");
        try {
            img1 = new ImagePanel(this, cardPaths1,x1,y1,Color.green);
            img2 = new ImagePanel(this, cardPaths2,x2,y2,Color.blue);
            img3 = new ImagePanel(this, cardPaths3,x3,y3,Color.red);
        } catch (IOException ex) {
            Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        }
 
        img1.setLocation(x1,y1);
        getContentPane().add(img1);
        img2.setLocation(x2,y2);
        getContentPane().add(img2);
        img3.setLocation(x3,y3);
        getContentPane().add(img3);
 
        setVisible(true);
    }
}
 
class ImagePanel extends JPanel{
    BufferedImage image;
    int x,y;
    MainWindow mainWin;
 
    public ImagePanel(MainWindow win, String p, int x, int y, Color c) throws IOException{
        this.x=x;
        this.y=y;
        mainWin = win;
        String path;
        path = "src/images/" + p + ".gif";
        image = ImageIO.read(new File(path));
 
        setSize(image.getWidth(), image.getHeight());
        setBackground(c);
    }
 
    protected void paintComponent(Graphics g){
        super.paintComponent(g);
        g.drawImage(image, x, y, mainWin);
    }
}

Open in new window

5h.gif
2c.gif
8d.gif
output.gif
0
 
ksivananthCommented:
set opaque false to all panels!
0
 
ksivananthCommented:
like this,

public ImagePanel(String p, int x, int y, Color c) throws IOException{
        this.x=x;
        this.y=y;
        mainWin = win;
        String path = "src/images/"+p+".gif";
        image = ImageIO.read(new File(path));
        setOpaque(false) ;
        setSize(image.getWidth(), image.getHeight());
    }
0
 
mitzdadonAuthor Commented:
I have done that as well ksivananth, but this causes only the last card (8d) to be displayed. The otehrs cant be seen at all!
0
 
CEHJCommented:
To get absolute placement of components (not images) like that you should probably use a null layout and place them by coordinates
0
 
CEHJCommented:
You also need to change the image coords:
g.drawImage(image, 0, 0, mainWin);

Open in new window

0
 
mitzdadonAuthor Commented:
Hi CEHJ. As you can see, thats what I have done in teh second set of code that I posted.
        img1.setLocation(x1,y1);
        getContentPane().add(img1);
        img2.setLocation(x2,y2);
        getContentPane().add(img2);
        img3.setLocation(x3,y3);
        getContentPane().add(img3);
 
0
 
mitzdadonAuthor Commented:
CEHJ. That has improved things. It now makes all the cards appear, but the last one that was added (8d) is drawn as (0,0), whereas the others 2 are drawn as specified by teh x,y values.
0
 
mitzdadonAuthor Commented:
Here is a screenshot..
output.gif
0
 
CEHJCommented:
This is my screen after implementing my own advice:
cards.png
0
 
mitzdadonAuthor Commented:
Thats strange...not sure why I don't get the same as you. Did you change the layout as well, or only the co-ordinates of the image?
0
 
CEHJCommented:
(Don't forget to set the null layout)
0
 
CEHJCommented:
:-)
0
 
mitzdadonAuthor Commented:
Sorry...forget to add my comments!

Thanks very much CEHJ. I didnt realise the impact of setting teh layout to null on this scenario. It never even crossed my mind. The naswer you provided was spot on.

thanks again.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 7
  • 7
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now