16

I want to draw in Java's Canvas but can't get it work because I don't know what I'm doing. Here's my simple code:

import javax.swing.JFrame;
import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Color;

public class Program
{
    public static void main(String[] args)
    {
        JFrame frmMain = new JFrame();
        frmMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmMain.setSize(400, 400);

        Canvas cnvs = new Canvas();
        cnvs.setSize(400, 400);

        frmMain.add(cnvs);
        frmMain.setVisible(true);

        Graphics g = cnvs.getGraphics();
        g.setColor(new Color(255, 0, 0));
        g.drawString("Hello", 200, 200);
    }
}

Nothing appears on the window.

Am I wrong to think that Canvas is a paper and Graphics is my Pencil? Is that how it works?

kazinix
  • 28,987
  • 33
  • 107
  • 157

4 Answers4

41

Suggestions:

  • Don't use Canvas as you shouldn't mix AWT with Swing components unnecessarily.
  • Instead use a JPanel or JComponent.
  • Don't get your Graphics object by calling getGraphics() on a component as the Graphics object obtained will be transient.
  • Draw in the JPanel's paintComponent() method.
  • All this is well explained in several tutorials that are easily found. Why not read them first before trying to guess at this stuff?

Key tutorial links:

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • 7
    Thanks! I did search the web. Yes they can be found easily, but cannot be understood easily. – kazinix Mar 08 '12 at 04:51
  • Wish I could give upvote to each point, but seems like not to use Canvas for Swing at the first place holds a major weight. – nIcE cOw Mar 08 '12 at 08:04
  • 2
    Good points. But keep in mind people will find your answer also when searching for this subject. That's why I think you should include links to the tutorials you mentioned. – Tim Nov 21 '13 at 13:26
  • 2
    You get an upvote on the strength of *I want to draw in Java's Canvas but can't get it work because I don't know what I'm doing.* alone. – Charlie Martin Feb 14 '20 at 21:39
7

You've got to override your Canvas's paint(Graphics g) method and perform your drawing there. See the paint() documentation.

As it states, the default operation is to clear the canvas, so your call to the canvas' graphics object doesn't perform as you would expect.

Thorn G
  • 12,620
  • 2
  • 44
  • 56
1

Why would the first way not work. Canvas object is created and the size is set and the grahpics are set. I always find this strange. Also if a class extends JComponent you can override the

paintComponent(){
  super...
}

and then shouldn't you be able to create and instance of the class inside of another class and then just call NewlycreateinstanceOfAnyClass.repaint();

I have tried this approach for some game programming I have been working and it doesn't seem to work the way I think that it should be.

Doug Hauf

Spudley
  • 166,037
  • 39
  • 233
  • 307
doug hauf
  • 11
  • 2
1

The following should work:

public static void main(String[] args)
{
    final String title = "Test Window";
    final int width = 1200;
    final int height = width / 16 * 9;

    //Creating the frame.
    JFrame frame = new JFrame(title);

    frame.setSize(width, height);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(null);
    frame.setResizable(false);
    frame.setVisible(true);

    //Creating the canvas.
    Canvas canvas = new Canvas();

    canvas.setSize(width, height);
    canvas.setBackground(Color.BLACK);
    canvas.setVisible(true);
    canvas.setFocusable(false);


    //Putting it all together.
    frame.add(canvas);

    canvas.createBufferStrategy(3);

    boolean running = true;

    BufferStrategy bufferStrategy;
    Graphics graphics;

    while (running) {
        bufferStrategy = canvas.getBufferStrategy();
        graphics = bufferStrategy.getDrawGraphics();
        graphics.clearRect(0, 0, width, height);

        graphics.setColor(Color.GREEN);
        graphics.drawString("This is some text placed in the top left corner.", 5, 15);

        bufferStrategy.show();
        graphics.dispose();
    }
}
Llewv
  • 123
  • 14