How to initialize Graphics g?

68,084

Solution 1

You never call paint() or paintComponent() yourself, you always go through repaint() which will take care of setting up the appropriate Graphics

Just to show what @mKorbel is referring to:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class Lives extends JPanel {
    private int lives;
    private ImageIcon gameOverImage;

    public Lives() {
        try {
            gameOverImage = new ImageIcon(new URL("http://imgup.motion-twin.com/dinorpg/0/f/77acf80b_989624.jpg"));
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        lives = 5;
    }

    public void removeLife() {
        if (lives > 0) {
            lives--;
            System.out.println("Left lives: " + lives);
            repaint();
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (lives > 0) {
            System.out.println("Still have " + lives + " lives");
            g.setColor(Color.WHITE);
            g.fillRect(5 * 20, 25 * 20, 100, 30);
            g.setColor(Color.BLACK);
            String result = "Lives: " + lives;
            g.drawString(result, 6 * 20, 26 * 20);
        } else if (gameOverImage != null) {
            System.out.println("Game over");
            int x = (getWidth() - gameOverImage.getIconWidth()) / 2;
            int y = (getHeight() - gameOverImage.getIconHeight()) / 2;
            g.drawImage(gameOverImage.getImage(), x, y, gameOverImage.getIconWidth(), gameOverImage.getIconHeight(), this);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(800, 600);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame(Lives.class.getSimpleName());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                final Lives lives = new Lives();
                frame.add(lives);
                frame.pack();
                frame.setVisible(true);
                // Dummy timer that reduces the lives every second. For demo purposes only of course
                Timer t = new Timer(1000, new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        lives.removeLife();
                    }
                });
                t.start();
            }
        });
    }
}

Solution 2

  • for public void paint(Graphics g) { is there missed container,

  • JPanel (in some cases JComponent) could be container for todays Java

  • have to use paintComponent instead of paint()

  • inside paintComponent you can to flag for paintGameOverScreen, then there paint only BufferedImage

  • prepare all Objects before, as local variable, do not load any FileIO (load images) inside paint(), paintComponent()

Solution 3

Here is how I did:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

public class InitializeGraphics
  {
        static BufferedImage buffer = null;
        static int height = 10;
        static int width = 10;
        static Graphics2D g2;

        public InitializeGraphics() {
                buffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB_PRE);
                g2 = buffer.createGraphics();
                g2.fillOval(2, 2, 2, 2);
                g2.dispose();
        }
        protected void paintComponent(Graphics g) {
                int x = 0;
                int y = 0;
                g.drawImage(buffer, x, y, width, height, null);
        }
        public Graphics2D getGraphics(){
                return g2;
        }
    }

Then somewhere: InitializeGraphics instance=new InitializeGraphics(); Graphics2D gG2 = instance.getGraphics();

Share:
68,084
redundant6939
Author by

redundant6939

Updated on September 06, 2020

Comments

  • redundant6939
    redundant6939 over 3 years

    I want to display a GameOver image in a pacman game after lives are over. But I call the paintGameOverScreen(Graphics g) and then I need to initialize g. Is there any other way to do this?

    This is my Lives class

    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.image.BufferedImage;
    
    import javax.imageio.ImageIO;
    import javax.swing.ImageIcon;
    
    
    public class Lives{
    
    private int lives;
    
    
    public Lives() {
        lives = 1;
    }
    
    public void removeLife() {
    
            lives--;
            if(lives==0){
                System.out.println("END GAME");
                paintGameOverScreen(g);
                System.exit(0);
            }
    }
    
    public void paintGameOverScreen(Graphics g) {
    
    
                ImageIcon i = new ImageIcon("src\image");
                Image image = i.getImage();
                int x = 0;
                int y = 0;
                g.drawImage(image, x, y, 100,100,null);
    }
    
    
    public void paint(Graphics g) {
        g.setColor(Color.WHITE);
        g.fillRect(5*20, 25*20, 100, 30);
        g.setColor(Color.BLACK);
        String result = "Lives: " + lives;
        g.drawString(result, 6*20, 26*20);
    }
    }
    
  • David Kroukamp
    David Kroukamp over 11 years
    +1 some good advices sir :). Also OP must not forget super.paintComponent(..) call
  • trashgod
    trashgod over 11 years
    For reference, "Swing programs should override paintComponent() instead of overriding paint()."—Painting in AWT and Swing: The Paint Methods.