My JFrame doesn't show anything

I am trying to create a simple base game for my class in Game Engine Architecture. But my JFrame just doesn't show anything.

My code is currently structured as follows:

.Java implementation (This is some arbitrary implementation of the Engine package that I create)

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 main flow of actions at the moment (from what I see):

  • I create a new World object in implementation
  • World-constructor is called with the given parameters
  • Set window title (this works)
  • I am creating a new SpritePanel object with this bgPath
  • The SpritePanel constructor is called and installs ImageIcon in the image that exists in this path
  • SpritePanel is added to the frame in BorderLayout.CENTER
  • I am adding a new JPanel to the frame in BorderLayout.CENTER
  • I set the size and stuff
  • I pack and set the frame to visible
  • I check and repaint

The thing is, the paintComponent methods in JPanel and SpritePanel do not seem to be called. As you can see, I added System.out.println to the paintComponent for SpritePanel, and this line is never executed.

Another thing I noticed is that the package seems to know that there are components. Because if I comment on three lines

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

The window size at program startup decreases to the size of the "bottom" -JPanel. I do not see the JLabel that I added to the panel, but the window size is the size. So the pack () method seems to find the sizes of my components.

If I comment on the three lines that add the bottom panel, and the window size is reduced to the height and width obtained from the standard icons.

I tried different things to make it work, but to no avail. I programmed with Swing before and made working programs, but I just can't find the problem here.

Help really appreciate.

+6
source share
2 answers

Something may be wrong with yours with your string path. What you should do, although instead of reading the file, you should read the URL by loading it from the class path. During deployment, you will find that the file path will not work, so it’s best to pack the image as an embedded resource by placing the image in the class path. I had no problems with this. Here is what I did.

  • Change the path to the path relative to the class path

     World w = new World("Hej", "/resources/stackoverflow5.png", 1024, 768); 
  • Changed loading from file to download from url from my class path

     background = new ImageIcon(SpritePanel.class.getResource(bgPath)); 
  • Put the image in the resources package in my class path

enter image description here

Everything works perfectly

enter image description here

 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 are already pack() . Best to pack anyway.
  • Put pack() before setLocationRelativeTo() . If you pack() after, you will notice that your frame will not be in the right place.
  • Launch Swing applications from a Stream Event Manager (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 the frame to fill the screen, do not set the size. Different cars have different screen sizes. Use setExtendedState(JFrame.MAXIMIZED_BOTH);

  • In addition, your setSize() will not work because you are calling pack() after.
+5
source

My problem was that I overridden the getWidth () and getHeight () methods in my World class. But look at peeskillets answer on how to make things better!

0
source

All Articles