2

so I've been working on my program and I am having trouble getting setting up a JFrame with a background image of a network map and then setting a JPanel using a MigLayout on top of the JFrame which will allow me to place images in accordance to the network map. I have seen several different ways on how to set a background image and have tried using an example I found elsewhere on this site but it's not quite working. Also, I researched more on this and found that having a JPanel ontop of a JFrame may prevent the JFrame background image from being seen. I was hoping that someone could take a look at my code and let me know if that is the case.

Here is my class to set the background:

public class bwMonBackground extends JFrame {
    Image img;
    public bwMonBackground() {
        try {
            img = ImageIO.read(new File("/Users/pwopperer/workspace/BWmon/src/customer_vlans.jpg"));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
public void paintComponent(Graphics g)
{
    super.paintComponents(g);
    g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
}

}

Here is my main:

public class bwMonBackgroundMain {

    public static void main( String[] args )
        {
            bwMonBackground frame = new bwMonBackground();
            frame.setLayout(new FlowLayout(FlowLayout.LEFT,10,20));
            migLayout testing = new migLayout();
            frame.add(testing.createLayout());
            frame.setVisible(true);
            frame.setResizable(false);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();

        }
}

EDIT: When I run it like this, I only get a JPanel with the 6 JLabels I added into it

mKorbel
  • 109,525
  • 20
  • 134
  • 319
exit_1
  • 1,240
  • 4
  • 13
  • 32

1 Answers1

3

It's been a little nit picky, but you should always call super.paintComponent unless you have a REALLY, REALLY good reason not to.

Also, you should provide Graphics.drawImage with a ImageObserver where possible. Basically this means if the image processing is taking place in another thread, the ImageObserver will not notified of changes and updated automatically ;)

public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    g.drawImage(img, 0, 0, this);
}

When placing components onto your map, you need to make sure they a transparent (JComponent.setOpaque(false)). This will allow the background to show through.

Obviously, you could choose some components to be opaque so they are more easily readable or provide AlphaComposites to provide translucent effects.

Additional Ideas

I wouldn't override JFrame in this manner. Frames have content panes, which are responsible for the core content.

Besides, from memory, JFrame doesn't have a paintComponent method :P

I would instead override JPanel (or JComponent) and user there paintComponent method instead, then either add this panel to the frames content pane or set it as the content pane itself (frame.setContentPane(...) - just beware, you do this BEFORE adding any other components to the frame, as this will effectively remove them from the UI ;))

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Thankyou, I called super.paintComponents and will update my code. Is there a tutorial or example you would recommend that demonstrates the usage of ImageObserver that you are recommending? – exit_1 Aug 08 '12 at 01:58
  • Really, you don't need to worry about it to much for what you are doing, it is implemented by `Component` and thus implemented by `JFrame` on you behalf ;) – MadProgrammer Aug 08 '12 at 02:00
  • @Pat if you're really desperate to see `ImageObserver` in action, you can take a look at http://www.daniweb.com/software-development/java/threads/177666/imageobserver-and-animated-gifs# – MadProgrammer Aug 08 '12 at 02:05