Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java how to add image as background in layout

I have a class that uses a CardLayout which has two cards that have a button on them. What I would like to be able to do is put an image that would act like a background such as a desktop background in Windows. The program eventually will have several different cards and I'd like to be able to put different backgrounds on each card. I've tried many suggestions posed in other similar questions on this site as well as whatever I can find through googling it, but I just can't seem to get it to work. I understand that with the CardLayout I can't put a panel on top of a panel, so putting an image on a JPanel wouldn't work. So my question is, based off the code posted below, is there a better way for me to setup my layout so that it works better, and also, how should I approach displaying the image so that it is in the background of the buttons? Any help would be greatly appreciated.

import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.*;

public class Cards implements ActionListener {    
private JPanel cards;
private JButton button1;
private JButton button2;
private Image backgroundImage;

public void addComponentToPane(Container pane) throws IOException {
    backgroundImage = ImageIO.read(new File("background.jpg"));

    //create cards
    JPanel card1 = new JPanel()
    {
        @Override
        public void paintComponent(Graphics g)
        {
            g.drawImage(backgroundImage, 0, 0, null);
        }
    };
    JPanel card2 = new JPanel();
    button1 = new JButton("Button 1");
    button2 = new JButton("Button 2");
    button1.addActionListener(this);
    button2.addActionListener(this);        
    card1.add(button1);        
    card2.add(button2);
    //create panel that contains cards
    cards = new JPanel(new CardLayout());
    cards.add(card1, "Card 1");
    cards.add(card2, "Card 2");
    pane.add(cards, BorderLayout.SOUTH);        
}

public void itemStateChanged(ItemEvent evt) {
    CardLayout cl = (CardLayout)(cards.getLayout());
    cl.show(cards, (String)evt.getItem());
}

public static void createAndShowGUI() throws IOException {
    //create and setup window
    JFrame frame = new JFrame("Frame"); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        
    //create and setup content pane
    Cards main = new Cards();
    main.addComponentToPane(frame.getContentPane());        
    //display window
    frame.pack();
    frame.setSize(800, 600);
    frame.setResizable(false);
    frame.setVisible(true);
}

public void actionPerformed(ActionEvent ae) {
    if (ae.getSource() == button1) {
        CardLayout cl = (CardLayout) (cards.getLayout());
        cl.show(cards, "Card 2");     
    } else if (ae.getSource() == button2) {
        CardLayout cl = (CardLayout) (cards.getLayout());
        cl.show(cards, "Card 1");
    }        
}            

public static void main(String[] args) {
    //set look and feel
    try {
        UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
    } catch (UnsupportedLookAndFeelException ex) {
        ex.printStackTrace();
    } catch (IllegalAccessException ex) {
        ex.printStackTrace();
    } catch (InstantiationException ex) {
        ex.printStackTrace();
    } catch (ClassNotFoundException ex) {
        ex.printStackTrace();
    }                

    //schedule job for the event dispatch thread creating and showing GUI        
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {                
                try {
                    createAndShowGUI();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

        }
    });     
}   
}
like image 607
Jarod Avatar asked Dec 16 '22 21:12

Jarod


2 Answers

You need to override the method paintComponent(Graphics g) of JPanel and use drawImage() on the Graphics object g as in this example.


Also, check these two examples by @trashgod:

  1. example.
  2. example.
like image 164
Eng.Fouad Avatar answered Dec 18 '22 09:12

Eng.Fouad


@Eng.Fouad's answer is well chosen, but the image probably dominates the layout. You might want to override getPreferredSize() as shown below. Then you can just pack() the window, and the size will be right. See also Loading Images Using getResource.

import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;

public class Cards implements ActionListener {

    private JPanel cards;
    private JButton button1;
    private JButton button2;
    private Image backgroundImage;

    public void addComponentToPane(Container pane) {
        try {
            backgroundImage = ImageIO.read(new File("background.jpg"));
        } catch (IOException ex) {
            ex.printStackTrace(System.err);
        }
        //create cards
        JPanel card1 = new JPanel() {

            @Override
            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.drawImage(backgroundImage, 0, 0, null);
            }

            @Override
            public Dimension getPreferredSize() {
                return new Dimension(
                    backgroundImage.getWidth(null),
                    backgroundImage.getHeight(null));
            }
        };
        JPanel card2 = new JPanel();
        button1 = new JButton("Button 1");
        button2 = new JButton("Button 2");
        button1.addActionListener(this);
        button2.addActionListener(this);
        card1.add(button1);
        card2.add(button2);
        //create panel that contains cards
        cards = new JPanel(new CardLayout());
        cards.add(card1, "Card 1");
        cards.add(card2, "Card 2");
        pane.add(cards, BorderLayout.SOUTH);
    }

    public void itemStateChanged(ItemEvent evt) {
        CardLayout cl = (CardLayout) (cards.getLayout());
        cl.show(cards, (String) evt.getItem());
    }

    public static void createAndShowGUI() {
        //create and setup window
        JFrame frame = new JFrame("Frame");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //create and setup content pane
        Cards main = new Cards();
        main.addComponentToPane(frame.getContentPane());
        //display window
        frame.pack();
        frame.setVisible(true);
    }

    public void actionPerformed(ActionEvent ae) {
        if (ae.getSource() == button1) {
            CardLayout cl = (CardLayout) (cards.getLayout());
            cl.show(cards, "Card 2");
        } else if (ae.getSource() == button2) {
            CardLayout cl = (CardLayout) (cards.getLayout());
            cl.show(cards, "Card 1");
        }
    }

    public static void main(String[] args) {
        //schedule job for the event dispatch thread creating and showing GUI        
        EventQueue.invokeLater(new Runnable() {

            public void run() {
                    createAndShowGUI();
            }
        });
    }
}
like image 20
trashgod Avatar answered Dec 18 '22 10:12

trashgod