0

I'm currently working with JFrame and I'm trying to draw a rectangle but I don't know how to execute the code paint(Graphics g), how do I get the Graphics object?

package com.raggaer.frame;

import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JFrame;

public class Frame {

    private JFrame frame;

    public Frame() {

        this.frame = new JFrame("Java Snake");
        this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.frame.setSize(new Dimension(500, 500));

        // DRAW??

        this.frame.setVisible(true);

    }

    public void paint(Graphics g) {

        g.drawRect(10, 10, 200, 200);
    }
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
Raggaer
  • 3,244
  • 8
  • 36
  • 67
  • 2
    Take a look at [Performing Custom Painting](http://docs.oracle.com/javase/tutorial/uiswing/painting/) and [Painting in AWT and Swing](http://www.oracle.com/technetwork/java/painting-140037.html) for more details about how painting in Swing should be done – MadProgrammer Apr 17 '14 at 00:29

1 Answers1

4

Just call frame.repaint() (which should be called once automatically) to make it repaint the graphics. No need to provide your own Graphics object.

Side note, you should be using a JPanel with paintComponent(Graphics) instead. This will make handling of events a lot easier, especially for a game like snake.


Here is a small code example on Stack Overflow: Java drawing on JPanel which on a JFrame

And one I made myself with usage of Java 8:

import javax.swing.*;
import java.awt.*;

/**
 * @author Obicere
 */
public class PaintExample {

    public PaintExample() {

        final JFrame frame = new JFrame("Paint Example");
        final MyPanel panel = new MyPanel();

        frame.add(panel);

        frame.pack();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(final String[] args) {
        SwingUtilities.invokeLater(PaintExample::new);
    }


    public class MyPanel extends JPanel {

        @Override
        public void paintComponent(final Graphics g) {
            super.paintComponent(g);

            g.setColor(Color.YELLOW);
            g.fillOval(0, 0, 50, 50);
            g.setColor(Color.BLACK);
            g.drawOval(0, 0, 50, 50);

            g.drawLine(20, 10, 20, 20);
            g.drawLine(30, 10, 30, 20);

            g.drawArc(15, 15, 20, 20, 180, 180);


            g.drawString("Drawing with swing!", 10, 100);
        }

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

    }
}

enter image description here


As request of your comment, I also modified the program to display objects upon request:

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.LinkedList;

/**
 * @author Obicere
 */
public class PaintExample {


    public PaintExample() {
        final JFrame frame = new JFrame("Paint Example");
        final MyPanel panel = new MyPanel();

        frame.add(panel);

        frame.pack();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(final String[] args) {
        SwingUtilities.invokeLater(PaintExample::new);
    }


    public class MyPanel extends JPanel {

        private final LinkedList<SmileyFace> faces;

        public MyPanel() {
            faces = new LinkedList<>();
            addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {
                    faces.add(new SmileyFace(e.getX(), e.getY()));
                    MyPanel.this.repaint(); // Refresh the display on the screen
                }
            });
        }

        @Override
        public void paintComponent(final Graphics g) {
            super.paintComponent(g);
            faces.stream().forEach((e) -> e.render(g));
        }

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

    }

    public class SmileyFace {

        private final int x;
        private final int y;

        public SmileyFace(final int x, final int y) {
            this.x = x;
            this.y = y;
        }

        public void render(final Graphics g) {

            g.setColor(Color.YELLOW);
            g.fillOval(x, y, 50, 50);
            g.setColor(Color.BLACK);
            g.drawOval(x, y, 50, 50);

            g.drawLine(x + 20, y + 10, x + 20, y + 20);
            g.drawLine(x + 30, y + 10, x + 30, y + 20);

            g.drawArc(x + 15, y + 15, 20, 20, 180, 180);
        }

    }

}

enter image description here

Community
  • 1
  • 1
Obicere
  • 2,999
  • 3
  • 20
  • 31
  • 3
    And don't forget to call `super.paintComponent` when you do (override `paintComponent` – MadProgrammer Apr 17 '14 at 00:27
  • Is there a way I can store my drawings on a variable so I can later modify them? like store g.drawString("score"...) to update it – Raggaer Apr 17 '14 at 00:38
  • 1
    @AlvaroCarvajalNakosmai you'd want to avoid artifacts (the sole reason to call `super.paintComponent(g)`). The best way would be to store what you want to draw as a variable, then inside `paintComponent(Graphics)`, you draw them to the screen. – Obicere Apr 17 '14 at 00:41