Search code examples
javaswingjframejlabel

Send JFrame ImageIcon to the back of Frame


I'm on the final part of my project and I'm having trouble sending my imported image "ship.png" to the back.

I have radio buttons set up inside of my class and I want to be able to see those radio buttons on top of ship.png that I imported.

Here's what I've tried so far but to no avail. The image that I import always seems to be in front of the radio buttons and/or getting rid of them all together.

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

public class Project2_ScottHogan
{
  public static void main(String[] args) throws IOException
  {
    String path = "D:/CSCI_1301/Project2/ship.png";
    File file = new File(path);
    BufferedImage shiplayout = ImageIO.read(file);
    JLabel label = new JLabel(new ImageIcon(shiplayout));

    JFrame main_frame = new JFrame("Welcome to Murracruise: The #1 cruise-line in the nation!"); //Sets a title for the JFrame
    main_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Closes the JFrame when exiting

    Cabin_Choice choice = new Cabin_Choice("", "", "", "", "", "", "", 0.00); //Calls upon the constructor of my Cabin_Choice class
    main_frame.getContentPane().add(choice); //Places choice into the current JFrame pane
    main_frame.setContentPane(label);

    main_frame.pack(); //Sizes the frame
    main_frame.setVisible(true); //Allows us to see the frame





  } //Ends the main method
} //Ends the class

And here is where I set up the radio buttons inside my Cabin_Choice class:

description = new JLabel("Choose your Cabin or Suite"); //Creates the label
description.setFont(new Font("Helonia", Font.BOLD, 28)); //Changes the font to Helonia and boldens the text for description

cabin1 = new JRadioButton("Cabin 11-1");
cabin2 = new JRadioButton("Cabin 11-2");
cabin3 = new JRadioButton("Cabin 11-3");
cabin4 = new JRadioButton("Cabin 11-4");
cabin5 = new JRadioButton("Cabin 11-5");
cabin6 = new JRadioButton("Cabin 11-6");
cabin7 = new JRadioButton("Cabin 11-7");
cabin8 = new JRadioButton("Cabin 11-8");
cabin9 = new JRadioButton("Cabin 11-9");
cabin10 = new JRadioButton("Cabin 11-10");
suite1 = new JRadioButton("Suite 11-S1");
suite2 = new JRadioButton("Suite 11-S2");

cabin1.setForeground(Color.white);
cabin2.setForeground(Color.white);
cabin3.setForeground(Color.white);
cabin4.setForeground(Color.white);
cabin5.setForeground(Color.white);
cabin6.setForeground(Color.white);
cabin7.setForeground(Color.white);
cabin8.setForeground(Color.white);
cabin9.setForeground(Color.white);
cabin10.setForeground(Color.white);
suite1.setForeground(Color.white);
suite2.setForeground(Color.white);

cabin1.setBackground(new Color(31, 21, 202)); //This sets the background to my own custom color of blue
cabin2.setBackground(new Color(31, 21, 202)); 
cabin3.setBackground(new Color(31, 21, 202));
cabin4.setBackground(new Color(31, 21, 202));
cabin5.setBackground(new Color(31, 21, 202));
cabin6.setBackground(new Color(31, 21, 202));
cabin7.setBackground(new Color(31, 21, 202));
cabin8.setBackground(new Color(31, 21, 202));
cabin9.setBackground(new Color(31, 21, 202));
cabin10.setBackground(new Color(31, 21, 202));
suite1.setBackground(new Color(31, 21, 202)); //This sets the background for the suites to a custom purple color
suite2.setBackground(new Color(31, 21, 202)); //Custom purple color for the background of suite 2

//The following block of code puts the radio buttons into a group
//so that the user can only select 1 cabin or suite at a time
ButtonGroup group = new ButtonGroup();
group.add(cabin1);
group.add(cabin2);
group.add(cabin3);
group.add(cabin4);
group.add(cabin5);
group.add(cabin6);
group.add(cabin7);
group.add(cabin8);
group.add(cabin9);
group.add(cabin10);
group.add(suite1);
group.add(suite2);

//
Cabin_Listener cabinlisten = new Cabin_Listener();
cabin1.addActionListener(cabinlisten);
cabin2.addActionListener(cabinlisten);
cabin3.addActionListener(cabinlisten);
cabin4.addActionListener(cabinlisten);
cabin5.addActionListener(cabinlisten);
cabin6.addActionListener(cabinlisten);
cabin7.addActionListener(cabinlisten);
cabin8.addActionListener(cabinlisten);
cabin9.addActionListener(cabinlisten);
cabin10.addActionListener(cabinlisten);
suite1.addActionListener(cabinlisten);
suite2.addActionListener(cabinlisten);

//
add(description);
add(cabin1);
add(cabin2);
add(cabin3);
add(cabin4);
add(cabin5);
add(cabin6);
add(cabin7);
add(cabin8);
add(cabin9);
add(cabin10);
add(suite1);
add(suite2);

//
setBackground(Color.white); //Sets the background for the entire frame
setPreferredSize(new Dimension(700,100)); //Sets the default size of the frame

Solution

    1. Call setContent before you add any new content to the frame
    2. Set the contentPane's layout manager (to something like BorderLayout), as JLabel doesn't have a layout manager set by default
    3. Set Cabin_Choice to be transparent using something like setOpaque(false), otherwise you won't see the background image

    For example...

    main_frame.setContentPane(label);
    main_frame.setLayout(new BorderLayout());
    main_frame.getContentPane().add(choice); //Places choice into the current JFrame pane
    

    Also, avoid using setPreferred/Minimum/MaximumSize in general, but in this case, it will have no effect as JLabel will ignore the values specified by it's child containers and only calculate the preferredSize based on the icon and text properties of the JLabel itself