Skip to main content

Background image in main JFrame

7 replies [Last post]
jacek
Offline
Joined: 2003-08-22
Points: 0

Any suggestions on how to do this properly? I want one background image for the entire app.

Which paint() should I override to draw the image?
The paint() of the main JFrame()?
The paint() of the root pane()
The paint() of the content pane()
The paint() of each JPanel displayed in the content pane()

I've tried the overriding the paint() in the main JFrame() and it does not work...

e.g.

public void paint(Graphics g) {
g.drawImage(backImage,0,0,this);
super.paint(g);
}

but it does not display my background image...

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Scott Violet

On Wed, Oct 15, 2003 at 05:13:11PM -0400, swing-feedback@javadesktop.org wrote:
> Any suggestions on how to do this properly? I want one background image for the entire app.
>
> Which paint() should I override to draw the image?
> The paint() of the main JFrame()?
> The paint() of the root pane()
> The paint() of the content pane()

paintComponent of the content pane is your best bet. Although to see
the background each of your widgets will need to have the opaque
property set to false. You'll want something like:

protected void paintComponent(Graphics g) {
if (isOpaque()) {
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
}
g.drawImage(backImage,0,0,this);
}

For better performance you could optimize the calls based on the clip
of the passed in graphics.

> The paint() of each JPanel displayed in the content pane()
>
> I've tried the overriding the paint() in the main JFrame() and it does not work...
>
> e.g.
>
> public void paint(Graphics g) {
> g.drawImage(backImage,0,0,this);
> super.paint(g);
> }
>
> but it does not display my background image...

By default Swing's content pane is opaque, so that it'll draw the
background over your image.

I would recommend taking a look at Shannon's article on painting
(http://java.sun.com/products/jfc/tsc/articles/swing2d/), it shows
some cool effects you can do with code like this.

-Scott

jacek
Offline
Joined: 2003-08-22
Points: 0

I presume this means I should subclass the content pane with a JComponent, correct?

Scott Violet

On Wed, Oct 15, 2003 at 05:32:05PM -0400, swing-feedback@javadesktop.org wrote:
> I presume this means I should subclass the content pane with a JComponent, correct?

Certainly. JPanel should also work fine.

-Scott

jacek
Offline
Joined: 2003-08-22
Points: 0

It's not working very well. When the window opens, it is blank. I have to minimize it, then right click on the window in the Windows bar at the bottom of the screen, in the right-click menu select "Maximize"...when it maximizes, then the image appears...but it doesn't appear the first time around when the window opens. What could I be doing wrong?

Here's the code for my content pane:

[code]
public class BackgroundImagePanel extends JComponent {

private Image backgroundImage = null;

/**
* Constructor
*/
public BackgroundImagePanel() {
super();
}

/**
* Returns the background image
* @return Background image
*/
public Image getBackgroundImage() {
return backgroundImage;
}

/**
* Sets the background image
* @param backgroundImage Background image
*/
public void setBackgroundImage(Image backgroundImage) {
this.backgroundImage = backgroundImage;
}

/**
* Overrides the painting to display a background image
*/
protected void paintComponent(Graphics g) {
if (isOpaque()) {
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
}
if (backgroundImage != null) {
g.drawImage(backgroundImage,0,0,this);
}
}

}
[/code]

And here's the code for my main frame:

[code]
public class MainFrame extends JFrame {

Image backImage;

/**
* Constructor
*/
public MainFrame() {
super("");

//handle window closing
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
this.setExtendedState(JFrame.MAXIMIZED_BOTH);

//get background image
backImage = Toolkit.getDefaultToolkit().getImage("wallpaper_adrift.jpg");
BackgroundImagePanel contentPane = new BackgroundImagePanel();
contentPane.setBackgroundImage(backImage);
this.setContentPane(contentPane);
}

/**
* Main
* @param args Command line arguments
*/
public static void main(String[] args) {
MainFrame frame = new MainFrame();
frame.setVisible(true);
}
}
[/code]

Any ideas what I am doing wrong here?

mgrev
Offline
Joined: 2003-08-12
Points: 0

Plz change to [ code ] instead. (Without the spaces between the bracket and code).

You can edit you old message to do this.

Regards,
Mikael

ps. Isn't the Toolkit loading the image asynchronically? If so you'll have to repaint the frame when it becomes available. Use a MediaTracker to check the image loading.

Message was edited by: mgrev

jacek
Offline
Joined: 2003-08-22
Points: 0

That was it!

I changed my image loading code to be:

[code]
ImageIcon icon = new ImageIcon("wallpaper_adrift.jpg");
backImage = icon.getImage();
[/code]

and it works perfectly now. Thanks for your help!

kwalrath
Offline
Joined: 2006-02-17
Points: 0

To make sure the code will work anywhere, it's probably
best to use the Class getResource method to get the path
to the image. Something like this:

[code]
java.net.URL imgURL = MainFrame.class.getResource("wallpaper_adrift.jpg");
ImageIcon icon = new ImageIcon(imgURL);
backImage = icon.getImage();[/code]

The tutorial has more information about loading
images here:

http://java.sun.com/docs/books/tutorial/uiswing/misc/icon.html

-k-