Search code examples
javaswingjlabeljcomboboxinvisible

Java - Swing library - JComboBox on top of JLabel with image - invisible JLabel


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);




    }
   }

Solution

  • 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);
        }
    }