My JFrame doesn't show anything

image, java, jframe, loading, swing

Solution

Something may be wrong with your with your String path. What you should do though, instead o reading a file, you should be reading a URL, loading from the class path. At time of deployment, you'll find out that the file path won't work, so it's better to package your image as an embedded resource, putting the image in the class path. I had no problems when doing this. Here's what I did.

Change the path to a path relative to my class path

World w = new World("Hej", "/resources/stackoverflow5.png", 1024, 768);

Changed loading from a file to loading from a URL from my class path

background = new ImageIcon(SpritePanel.class.getResource(bgPath));

Put the image in `resources` package in my class path

Everything works fine

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Implementation {

    public static void main(String[] args) {
        World w = new World("Hej", "/resources/stackoverflow5.png", 1024, 768);
    }
}

class World extends JFrame {

    private static final long serialVersionUID = 1L;
    private SpritePanel spritePanel;
    private JPanel bottom;
    private int width;
    private int height;

    public World(String windowCaption, String bgPath, int width, int height) {
        super(windowCaption);

        spritePanel = new SpritePanel(bgPath);
        add(spritePanel, BorderLayout.CENTER);
        System.out.println(spritePanel);

        bottom = new JPanel();
        bottom.add(new JLabel("Hej"));
        add(bottom, BorderLayout.SOUTH);

        Dimension size = new Dimension(width, height);
        setSize(size);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        pack();
        setVisible(true);

        validate();
        repaint();
    }

    class SpritePanel extends JPanel {

        private static final long serialVersionUID = 1L;
        private ImageIcon background;
//private ArrayList<Sprite> sprites = new ArrayList<Sprite>();

        public SpritePanel(String bgPath) {
            background = new ImageIcon(SpritePanel.class.getResource(bgPath));
            setLayout(null);
            Dimension size = new Dimension(background.getIconWidth(), background.getIconHeight());
            setPreferredSize(size);
            setMaximumSize(size);
            setMinimumSize(size);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(background.getImage(), 0, 0, this);
            System.out.println("painted panel");
        }
    }
}

Side Notes

- No need to `setSize()`. You already `pack()`. It better to just pack anyway.

- Put the `pack()` before the `setLocationRelativeTo()`. If you `pack()` after, you'll notice your frame won't be in the desired location.

Run your Swing apps from the Event Dispatch Thread (EDT) like this

public static void main(String[] args){
    SwingUtilities.invokeLater(new Runnable(){
        @Override
        public void run() {
            new World("Hej", "/resources/stackoverflow5.png", 1024, 768);
        }
    });
}

If you want to make the frame fill the screen, don't set the size. Different machines have different screen sizes. Instead use `setExtendedState(JFrame.MAXIMIZED_BOTH);`

- Also, your `setSize()` won't work anyway because you're calling `pack()` after.

Problem

I am trying to build a simple basic to a game for my class in Game Engine Architecture. But my JFrame just wont show anything. My code is currently structured like this: Implementation.java (This is some arbitrary implementation of the Engine-package I'm creating) ``` public class Implementation { public static void main(String[] args){ World w = new World("Hej", "M:\\workspace\\SP6\\pics\\tulips.jpg",1024,768); } } ``` World.java ``` public class World extends JFrame{ private static final long serialVersionUID = 1L; private SpritePanel spritePanel; private JPanel bottom; private int width; private int height; public World(String windowCaption, String bgPath, int width, int height){ super(windowCaption); spritePanel = new SpritePanel(bgPath); add(spritePanel, BorderLayout.CENTER); System.out.println(spritePanel); bottom = new JPanel(); bottom.add(new JLabel("Hej")); add(bottom, BorderLayout.SOUTH); Dimension size = new Dimension(width,height); setSize(size); setLocationRelativeTo(null); setDefaultCloseOperation(EXIT_ON_CLOSE); pack(); setVisible(true); validate(); repaint(); } ``` SpritePanel.java ``` public class SpritePanel extends JPanel { private static final long serialVersionUID = 1L; private ImageIcon background; private ArrayList<Sprite> sprites = new ArrayList<Sprite>(); public SpritePanel(String bgPath){ background = new ImageIcon(bgPath); setLayout(null); Dimension size = new Dimension(background.getIconWidth(), background.getIconHeight()); setPreferredSize(size); setMaximumSize(size); setMinimumSize(size); } @Override protected void paintComponent(Graphics g){ super.paintComponent(g); g.drawImage(background.getImage(), 0, 0, this); System.out.println("painted panel"); } } ``` So the basic action flow at the moment (from what I can see): - I create a new World object in the Implementation - The World-constructor is called with the given parameters - The window caption is set (this works) - I create a new SpritePanel object with the given bgPath - The SpritePanel-constructor is called and sets the ImageIcon to the image that exists in the given path - The SpritePanel is added to the frame in BorderLayout.CENTER - I add a new JPanel to the frame in BorderLayout.CENTER - I set size and stuff - I pack and set the frame to visible - I validate and repaint The thing is the paintComponent methods in the JPanel and SpritePanel doesn't seem to get called. As you can see I added a System.out.println in the paintComponent for SpritePanel and that line is never executed. Another thing I noticed is that the pack seems to know that the components are there. Because if I comment the three lines ``` spritePanel = new SpritePanel(bgPath); add(spritePanel, BorderLayout.CENTER); System.out.println(spritePanel); ``` The windows size when I run the program is reduced to the size of the "bottom"-JPanel. I can't see the JLabel that I added to the panel but the window size is the size of it. So the pack() method seems to be finding the dimensions of my components. If I comment the three lines that adds the bottom panel as well the window size is reduced to no height and the width it gets from the standard icons. I've been trying different things to get it to work but to no avail. I have programmed with Swing before and made working programs but I just can't seem to find the problem here. Help very much appreciated.

Original source