ERIK UMHOEFER
ERIK UMHOEFER

Reputation: 19

Java Graphics Not Displaying

I have been trying to display the graphics for my game, but none of the graphics are being displayed on the panel.

Following is my code. The main class invokes the paint methods of the other two classes.

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Simulator extends JFrame implements KeyListener, Runnable, ActionListener {

    private final int WIDTH, HEIGHT;
    private Boolean right;
    private int xMotion;
    public Salt salt;
    public Player playR;
    Boolean running = false;
    private Thread thread;
    public static int score, highScore;
    private int saltSpeed;

    public Simulator(int width, int height) {
        JPanel panel = new JPanel();
        JFrame frame = new JFrame();
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setSize(width, height);
        panel.setBackground(Color.BLACK);
        frame.add(panel);

        playR = new Player();


        this.HEIGHT = height;
        this.WIDTH = width;
        int xCordSalt = (int) (Math.random() * 631);
        saltSpeed = 1;

        salt = new Salt(saltSpeed);
        right = true; 
        running = true;

    }


    public static void main(String[] args) {
        Simulator game = new Simulator(640, 480);

        game.start();
    }

    public void paintComponent(Graphics g)
    {


        salt.paint(g);
        playR.paint(g);



    }

    public void start() {

        running = true;
        thread = new Thread(this);
        thread.start();
        repaint();
        tick();
        run();


    }

    public void stop() {
        running = false;
        System.exit(0);
    }


    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_D) {
            right = true;
        } else if (e.getKeyCode() == KeyEvent.VK_A) {
            right = false;

        }

    }

    public void tick() {
        salt.tick(this, playR);
        playR.tick();

    }

    @Override
    public void keyReleased(KeyEvent e) {


    }

    @Override
    public void keyTyped(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_D)
        {
            playR.setDirection(true);
        }
        else if(e.getKeyCode() == KeyEvent.VK_A)
        {
            playR.setDirection(false);
        }

    }

    @Override
    public void run() {
        while (running) {
            tick();
            repaint();

            try {
                thread.sleep(7);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }



    public void incrementScore() {
        score++;

    }


    @Override
    public void actionPerformed(ActionEvent e) {
        repaint();
        tick();

    }

}

And here's the code for the method salt:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.ArrayList;



public class Salt extends Rectangle{

    private final int WIDTH = 10;
    private final int HEIGHT = 10;
    public int xCordSalt, yCordSalt;
    private int speed;
    Rectangle boundBox;
    public Salt(int speedx)
    {

        xCordSalt = (int)Math.random()*641;
        yCordSalt = 0;
        speed = speedx;
        boundBox = new Rectangle(xCordSalt, yCordSalt, WIDTH, HEIGHT);
        boundBox.setBounds(xCordSalt, yCordSalt, WIDTH, HEIGHT);



    }

    public void tick(Simulator sim, Player playR)
    {
        boundBox.setBounds(xCordSalt, yCordSalt, WIDTH, HEIGHT);

        if(yCordSalt >= 480)
        {
            //sim.stop();
        }

        else if(checkCollision(playR))
        {
            sim.incrementScore();
            speed++;
            yCordSalt = -speed;

        }


        yCordSalt = yCordSalt + speed;


    }




    public boolean checkCollision(Player playR)
    {
        if(this.getBoundBox().intersects(playR.getBoundBox()))
        {
            return true;
        }
        return false;
    }

    public void paint(Graphics g) {
        g.setColor(Color.WHITE);
        g.fillRect(xCordSalt, yCordSalt, WIDTH, HEIGHT);
    }

    public Rectangle getBoundBox()
    {
        return boundBox;
    }

    public double getSpeed()
    {
        return speed;
    }


}

And finally the method player, which uses the imageIcon class to display an image:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;

import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class Player extends JPanel {
    private int xCord, yCord;
    public Rectangle boundBox;
    private static ImageIcon ryan;
    boolean isRight;

    public Player() {
        ryan = new ImageIcon("E:\ryan.png");
        xCord = 640/2;
        yCord = 460;
        boundBox = new Rectangle(xCord, yCord, 20, 20);


    }

    public static void main(String[] args) {

    }

    public void tick() {

    }

    public void setDirection(Boolean right)
    {
        if(right)
            isRight = true;
        else
            isRight = false;
    }


    public void paint(Graphics g) {
        Graphics2D g2d = (Graphics2D)g;
        g2d.drawImage(ryan.getImage(), xCord, yCord, null);


    }

    public Rectangle getBoundBox()
    {
        return boundBox;
    }

}

Now some of it is incomplete, but I cannot realize why it is displaying no graphics whatsoever. When ran, only a black frame / panel appears. I added some print statements to the tick() methods of each class, the paint() methods of each class and the paintComponent() method, and the start() method. The game will start, run each class's tick method, but paintComponent() or any of the paint() methods are ever called!

Upvotes: 1

Views: 938

Answers (2)

MadProgrammer
MadProgrammer

Reputation: 347184

Let's start with the obvious...

public class Simulator extends JFrame ... {
    //...
    public void paintComponent(Graphics g) {

        salt.paint(g);
        playR.paint(g);

    }

JFrame doesn't have a method called paintComponent, so your paintComponent will never be called, so salt and playR will never painted.

You can test this by adding @Override to the paintComponent which does a compile time sanity check for you

public class Simulator extends JFrame ... {
    //...
    @Override
    public void paintComponent(Graphics g) {

        salt.paint(g);
        playR.paint(g);

    }

This will fail to compile.

Now, you could override paint instead, but because, because, because, because, because ... I wouldn't recommend it ...

Take a step back for a second. What is the JFrame really responsible for? Providing a container onto which you can add you gui and have it displayed on the screen. You're not really adding any new functionality to the JFrame, so I wouldn't use it as your "main" component, instead, I'd just create an instance of it and add what ever components you want to use to it.

Instead, I'd start with a JPanel and override its paintComponent method and put all your custom painting into it.

I would then use this component as a starting point for your core logic and controllers.

You might even create several components to act as things like the menu and option views and use a CardLayout or OverlayoutLayout to display them.

I'd also recommend having a look at How to Use Key Bindings instead of KeyListener while you're at it, this will answer your next question.

Upvotes: 2

gpasch
gpasch

Reputation: 2682

First you are creating a frame in excess - the class itself is a frame so no need for more:

    setSize(width, height);
    setVisible(true);

Second you add a panel on to it: that will cover everything;

Third JFrame doesn't have paintComponent - instead use paint().

Fourth, in starting the thread by calling start() the run() method will automatically be called - no need to call run().

Here's my working constructor and paint method:

public Simulator(int width, int height) {
    setSize(width, height);
    panel.setBackground(Color.BLACK);
    setVisible(true);

    try {
      bim=ImageIO.read(new File(.....));
    }
    catch (Exception ex) { ex.printStackTrace(); }


    this.HEIGHT = height;
    this.WIDTH = width;
    int xCordSalt = (int) (Math.random() * 631);
    saltSpeed = 1;

    right = true; 
    running = true;

}


public void paint(Graphics g)
{

  g.setColor(Color.magenta);
  g.fillRect(0, 0, 100, 100);
  g.drawImage(bim, 100, 0, null);

}

Upvotes: 0

Related Questions