2

I've looked at a ton of other questions where people have similar issues to what I'm having here (most solutions found by simple mistakes) but I can't for the life of me figure out why my graphics won't display in my jframe. I'm pretty new to Java Graphics so I'd appreciate all the help that I can get. (If someone thinks this is a repeat question, all I ask is that you wait until I get an answer before you close it)

Oh, also, when I run the program, it tells me that the repaint method is called, if that helps in some way

package game.try5;

import java.awt.Dimension;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Window {

    public Window() {
        JFrame frame = new JFrame("Epic Game");
        frame.setSize(800,600);
        frame.setLocationRelativeTo(null);
        frame.setLayout(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        GamePanel panel = new GamePanel();
        frame.add(panel);

        frame.setVisible(true);
    }

    public static void main(String[] args){
        Window window = new Window();
    }
}   

.

package game.try5;

import java.awt.Graphics;

import javax.swing.JPanel;

public class GamePanel extends JPanel{
    GameObject go = new GameObject(0,0,false,"Dog.jpg");

    public GamePanel(){
        repaint();
        System.out.println("Repaint method called");
    }
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        g.drawImage(go.getImg().getImage(), go.getxLoc(), go.getyLoc(), 50, 50, null);
        System.out.println("Graphics method called");
    }
}

.

package game.try5;

import java.awt.Dimension;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Window {

    public Window() {
        JFrame frame = new JFrame("Epic Game");
        frame.setSize(800,600);
        frame.setLocationRelativeTo(null);
        frame.setLayout(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        GamePanel panel = new GamePanel();
        frame.add(panel);

        frame.setVisible(true);
    }

    public static void main(String[] args){
        Window window = new Window();
    }
}   
Neeek
  • 53
  • 3
  • 1
    1) You've copied `Window` twice but there is no `GameObject`. 2) Java GUIs have to work on different OS', screen size, screen resolution etc. using different PLAFs in different locales. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556) along with layout padding and borders for [white space](http://stackoverflow.com/a/17874718/418556). 3) Comment out `frame.setLayout(null);` and you'll most likely see the game. – Andrew Thompson May 19 '15 at 14:47
  • You were right, it worked when I removed the "frame.setLayout(null)" line. What did you mean when you said that I've copied "Window" twice and that there is no GameObject? I didn't really get what you meant by that, also, what is the default layout if one is not declared? – Neeek May 19 '15 at 15:20
  • *"What did you mean when you said that I've copied "Window" twice and that there is no GameObject?"* Look at code in the **question**. ;) *"what is the default layout if one is not declared?"* It depends on which (version) of which component you mean. For a `Frame` (and possibly `JFrame` - cannot quite recall) it used to be `FlowLayout` but is now `BorderLayout`. For a `JPanel` it is a `FlowLayout`. I really don't like relying on any 'default' layout since Sun/Oracle rarely states them in the Java Docs and they should therefore be seen as 'open to change'. – Andrew Thompson May 19 '15 at 15:27

1 Answers1

2

Comment out frame.setLayout(null); and you'll most likely see the game.

  1. The default layout of a JFrame is currently a BorderLayout
  2. An object added to a BorderLayout without a constraint defaults to the CENTER.
  3. An object in the CENTER of a BorderLayout is stretched to the available with and height.
  4. Since the code calls frame.setSize(800,600); that available width and height is 800x600 pixels less the frame decorations.

A better all round approach is to:

  1. Have the custom painted component override getPreferredSize() to return a sensible value.
  2. Add the component to a container.
  3. Lastly, pack the top level window. This will make the frame the smallest size it needs to be in order to display the content.
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433