13

I am creating a simple GUI, and I want to have a background image (2048 X 2048) fill up the whole window and a square to the left top corner where the occasional 64 X 64 image can be loaded. How can this be done?

I already know how to make the JFrame a set size, its the image loading I need help with.

starball
  • 20,030
  • 7
  • 43
  • 238
CCD
  • 470
  • 1
  • 7
  • 19
  • 3
    Before one is able to submit such a post as mine, they are prompted to do just that. I did not find anything related so I continued on to write this. If I caused you an annoyance by posting this, I hope that is the greatest inconvenience you will have to face. – CCD Sep 13 '13 at 04:13
  • 2
    @Aaron, I've been over to the javaranch.com and to java-forums.org. They are nice over there. And they are competent too. The motto at the JavaRanch is "The JavaRanch, Friendly to Greenhorns". I'm interested in your question here, +1. – Kaydell Sep 14 '13 at 06:11
  • 1
    Please have a look at this answer, regarding how to [load images in your project](http://stackoverflow.com/a/9866659/1057230). And @Kaydell, please you too. Hope it helps :-) – nIcE cOw Sep 14 '13 at 06:12
  • Thanks, I appreciate all the interest and help! – CCD Sep 15 '13 at 05:44

4 Answers4

16

This is a simple example for adding the background image in a JFrame:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class BackgroundImageJFrame extends JFrame
{
    JButton b1;
    JLabel l1;

    public BackgroundImageJFrame()
    {
        setTitle("Background Color for JFrame");
        setSize(400,400);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);

        /*
        One way
        -----------------
        setLayout(new BorderLayout());
        JLabel background=new JLabel(new ImageIcon("C:\\Users\\Computer\\Downloads\\colorful design.png"));
        add(background);
        background.setLayout(new FlowLayout());
        l1=new JLabel("Here is a button");
        b1=new JButton("I am a button");
        background.add(l1);
        background.add(b1);
        */

        // Another way
        setLayout(new BorderLayout());
        setContentPane(new JLabel(new ImageIcon("C:\\Users\\Computer\\Downloads\\colorful design.png")));
        setLayout(new FlowLayout());
        l1=new JLabel("Here is a button");
        b1=new JButton("I am a button");
        add(l1);
        add(b1);
        // Just for refresh :) Not optional!
        setSize(399,399);
        setSize(400,400);
    }

    public static void main(String args[])
    {
        new BackgroundImageJFrame();
    }
} 
  • Click here for more info
ifconfig
  • 6,242
  • 7
  • 41
  • 65
Nambi
  • 11,944
  • 3
  • 37
  • 49
  • so the sesize() at the end refreshes the image? – CCD Sep 13 '13 at 14:39
  • @Aaron, I believe that rather than calling setSize() twice to refresh the window, it is better to always call setVisible(true) last of all and the windows will be drawn properly. – Kaydell Sep 14 '13 at 19:54
  • 1
    I've studied Nambi's code and learned something, but I changed the code, improving it I believe. Here is a link to my version of the code, with comments: https://gist.github.com/kaydell/6565219 – Kaydell Sep 14 '13 at 20:13
  • Thanks, all of this advice is very useful, and I appreciate all the help :) – CCD Sep 15 '13 at 05:45
  • Use pack over set size and let the layout manager deal with it. Call setVisible last to ensure that the frame paints itself properly the first time. – MadProgrammer Feb 04 '14 at 19:32
12

The best way to load an image is through the ImageIO API

BufferedImage img = ImageIO.read(new File("/path/to/some/image"));

There are a number of ways you can render an image to the screen.

You could use a JLabel. This is the simplest method if you don't want to modify the image in anyway...

JLabel background = new JLabel(new ImageIcon(img));

Then simply add it to your window as you see fit. If you need to add components to it, then you can simply set the label's layout manager to whatever you need and add your components.

If, however, you need something more sophisticated, need to change the image somehow or want to apply additional effects, you may need to use custom painting.

First cavert: Don't ever paint directly to a top level container (like JFrame). Top level containers aren't double buffered, so you may end up with some flashing between repaints, other objects live on the window, so changing it's paint process is troublesome and can cause other issues and frames have borders which are rendered inside the viewable area of the window...

Instead, create a custom component, extending from something like JPanel. Override it's paintComponent method and render your output to it, for example...

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

Take a look at Performing Custom Painting and 2D Graphics for more details

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
5

I used a very similar method to @bott, but I modified it a little bit to make there be no need to resize the image:

BufferedImage img = null;
try {
    img = ImageIO.read(new File("image.jpg"));
} catch (IOException e) {
    e.printStackTrace();
}
Image dimg = img.getScaledInstance(800, 508, Image.SCALE_SMOOTH);
ImageIcon imageIcon = new ImageIcon(dimg);
setContentPane(new JLabel(imageIcon));

Works every time. You can also get the width and height of the jFrame and use that in place of the 800 and 508 respectively.

Riccorbypro
  • 143
  • 2
  • 8
4

You can do:

setContentPane(new JLabel(new ImageIcon("resources/taverna.jpg")));

At first line of the Jframe class constructor, that works fine for me

bott
  • 188
  • 1
  • 2
  • 12