views:

268

answers:

2

Hi guys

I am attempting to overlay images on top of a background image using the standard java utilities. See the pictures below...

I have code that seems to create the background image (can you verify that it really works?) And I have created an extension of JPanel that I use to display images (the class is called ImagePanel)

However, when the program launches, the JFrame is only showing the second image, which then gets moved around as the window is resized.

I'd like to have the window open initially with the background image taking up the entirety of the window's space. I'd then like to have the second image displayed on top, at the location that I specify.

import javax.swing.*;
import java.awt.*;

public class ImageTest {




public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.getContentPane().setLayout(null);

    JPanel backgroundPanel = new JPanel();
    ImageIcon backgroundImage = new ImageIcon("C:\\Documents and Settings\\Robert\\Desktop\\ClientServer\\Poker Table Art\\TableAndChairs.png");
    JLabel background = new JLabel(backgroundImage);
    background.setBounds(0, 0, backgroundImage.getIconWidth(), backgroundImage.getIconHeight());
    frame.getLayeredPane().add(background, new Integer(Integer.MIN_VALUE));
    backgroundPanel.setOpaque(false);
    frame.setContentPane(backgroundPanel);

    ImagePanel button = new ImagePanel("C:\\Documents and Settings\\Robert\\Desktop\\ClientServer\\Poker Table Art\\button.png");
    JPanel cardContainer = new JPanel(new FlowLayout());


    frame.getContentPane().add(cardContainer);

    cardContainer.add(button);
    cardContainer.setBounds(100, 600, 200, 200);

    frame.pack();
    frame.setVisible(true);
  }
}

alt text

alt text

+3  A: 

I'd like to have the window open initially with the background image taking up the entirety of the window's space.

Then simply create a JLabel with an Icon and use the label as the content pane of the frame. When you pack the frame it will be assume the size of the image.

I'd then like to have the second image displayed on top, at the location that I specify.

Use a null layout for the above label. Now you can create additional JLabels with Icons and add them to the content pane and postion them using setBounds.

camickr
any reason why you would use JLabel's instead of JPanel
Allen
I just changed the JPanel holding the background image to have a null layout, and that solved the problem of getting the second image to overlay at the position of my choosing. However, the frame still opens with no size, any idea what i might be able to do?
Allen
after some tinkering it looks like it's actually working. thanks for the help
Allen
The question is why to you want to use a JPanel for a background image? Why do you want to write custom code when a JLabel already does this? The JLabel already calculates the preferred size based on the size of the image. Why do you want to write custom code to calculate the size of the panel? (ie. Why do you think the frame opens up with no size?) Why don't you try the suggestion first before commenting?
camickr
+2  A: 

You can set the preferred size of the background panel to the image's size:

backgroundPanel.setPreferredSize(new Dimension(
    backgroundImage.getIconWidth(), backgroundImage.getIconHeight()));

I would advocate following @camickr's approach. Not having previously experimented with setBounds() myself, here is a simple example to see the effect:

import javax.swing.*;
import java.awt.*;

public class ImageTest {

    public static void main(String[] args) {

        JFrame frame = new JFrame();
        JLabel label = new JLabel(new ElliptIcon(380, 260, Color.red));
        label.setLayout(new GridLayout(2, 2));
        frame.setContentPane(label);

        for (int i = 0; i < 4; i++) {
            label.add(new JLabel(new ElliptIcon(100, 60, Color.blue)));
        }

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    private static class ElliptIcon implements Icon {

        private int w, h;
        private Color color;

        public ElliptIcon(int w, int h, Color color) {
            this.w = w;
            this.h = h;
            this.color = color;
        }

        @Override
        public void paintIcon(Component c, Graphics g, int x, int y) {
            g.setColor(color);
            g.fillOval(x, y, w, h);
        }

        @Override
        public int getIconWidth() { return w; }

        @Override
        public int getIconHeight() { return h; }
    }
}
trashgod
Again why write custom code to draw the image and calculate the preferred size of the panel? This is done automatically by the JLabel. A JLabel is a container, just like a JPanel. So you can add components to it just as easy as you can a JPanel and you get the bonus of having the background image as well.
camickr
@camickr: I agree. I had never thought to set a `JLabel`'s layout, and I've updated my example to show using a `GridLayout`. The questioner might like to try this with `StarLayout`: http://mindprod.com/jgloss/starlayout.html
trashgod