1

It's my first post here, trynna be quick. I have a small JFrame window with JLabel with image as a background to said JFrame. JFrame also has 2 JButtons. To this point it worked well, until I decided to add JComboBox. Result of this action is now when I run my JFrame it shows blank, no background image from JLabel, no ComboBox visible, JButtons are shown tho. When I resize even a little this window, JLabel background image appears and everything is fine but it should be without resizing. What am I missing here? I'm very fresh with swing and am doing "game" for my java class project. Here is screenshots and code:

Running

After resizing

public class View_Startup extends JFrame {
    JLabel lBackground;
    JButton bStart,bExit;
    JComboBox cbResolutions;
    ImageIcon iBackground,iStart,iExit;
    Image icon;
    String resolutions[] = {"1280x720 HD","1366x768 WXGA","1600x900HD+","1920x1080 fullHD"};

    public View_Startup() {

        iBackground = new ImageIcon("xdddddddddd/resolution_background.jpg");
        iStart = new ImageIcon("xddddddddddd/iStart2.png");
        iExit = new ImageIcon("xdddddddddd/iExit2.png");    

        this.setSize(656,399);
        this.setTitle("xddddddddd");
        this.icon = Toolkit.getDefaultToolkit().getImage("C:xdddddddddd\\images.jpg"); 
        this.setIconImage(icon);
        this.setVisible(true);
        this.setLayout(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice defaultScreen = ge.getDefaultScreenDevice();
        Rectangle rect = defaultScreen.getDefaultConfiguration().getBounds();   
        int x=(int) rect.getMaxX();
        int y=(int) rect.getMaxY();
        this.setLocation(x/2-328,y/2-199);

        bStart = new JButton(iStart);
        bStart.setBounds(490,240,150,50);
        bStart.setOpaque(false);
        bStart.setContentAreaFilled(false);
        //bStart.setBorderPainted(false);
        add(bStart);

        bExit = new JButton(iExit);
        bExit.setBounds(490,300,150,50);
        bExit.setOpaque(false);
        bExit.setContentAreaFilled(false);
        //bExit.setBorderPainted(false);
        add(bExit);

        cbResolutions = new JComboBox(resolutions);
        cbResolutions.setBounds(490,180,150,50);
        add(cbResolutions);

        lBackground = new JLabel(iBackground);
        lBackground.setBounds(0,0,640,360);
        add(lBackground);




    }
   }
  • You have a combination of issues. `setLayout(null)` would be your first. Z-ordering of your components would be your second. [Have a look at this example](https://stackoverflow.com/questions/22162398/how-to-set-a-background-picture-in-jpanel/22162430#22162430) to see how you should use a `JLabel` as a background, but also, why you shouldn't use it and a better solution – MadProgrammer Jan 28 '18 at 01:51
  • Please see edits to answer – DontKnowMuchBut Getting Better Jan 28 '18 at 02:03

1 Answers1

3

Several problems here:

  • You're using null layouts, a dangerous and kludgy thing to do
  • You're calling setVisible(true) on the JFrame before you've fully constructed it. Only call this after adding all components.
  • You're using a JLabel as a background image displayer, but not using it also as a container to hold components.

Instead consider

  • Using a JPanel's paintComponent method to display the background image
  • Add this JPanel to your JFrame's contentPane or make it the contentPane
  • Give it a decent layout (and if need be, add nested non-opaque JPanels each with their own layouts if you need complex layouts)
  • Call .setVisible(true) on your JFrame after adding all components.

Something like this:

enter image description here

can be created with this code:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

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

public class LayoutExample extends JPanel {
    private static final long serialVersionUID = 1L;
    private BufferedImage background;
    private JButton startButton = new JButton("Start");
    private JButton exitButton = new JButton("Exit");
    private JComboBox<String> combo = new JComboBox<>(new String[] {"1280 x 780 HD"});

    public LayoutExample(BufferedImage background) {
        this.background = background;

        JPanel rightLowerPanel = new JPanel(new GridLayout(0, 1, 5, 5));
        rightLowerPanel.setOpaque(false);
        rightLowerPanel.add(combo);
        rightLowerPanel.add(startButton);
        rightLowerPanel.add(exitButton);

        JPanel rightPanel = new JPanel(new BorderLayout());
        rightPanel.setOpaque(false);
        rightPanel.add(rightLowerPanel, BorderLayout.PAGE_END);

        setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        setLayout(new BorderLayout());
        add(rightPanel, BorderLayout.LINE_END);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (background != null) {
            g.drawImage(background, 0, 0, this);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        if (background != null) {
            int w = background.getWidth();
            int h = background.getHeight();
            return new Dimension(w, h);
        }
        return super.getPreferredSize();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

    private static void createAndShowGui() {
        String imgPath = "https://pbs.twimg.com/media/DRHUe_tV4AA96G4.jpg";
        BufferedImage img = null;
        try {
            URL imageUrl = new URL(imgPath);
            img = ImageIO.read(imageUrl);
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
        LayoutExample mainPanel = new LayoutExample(img);
        JFrame frame = new JFrame("LayoutExample");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
}
  • "Call .setVisible(true) on your JFrame after adding all components." this line helped me. I do realise my project is completely amateur due to facts like null layout for example but I do not have time to master it and im gonna just make it working and after my 'daedline' i will keep working on it for myself and make it as professional as possible – Max Urbanowicz Jan 28 '18 at 13:28