Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPanel custom drawing using Graphics

I have a custom JPanel and sometimes throughout my program, I need to call a method which paints the screen black, that's it.

public void clearScreen() {
    Graphics g = getGraphics();
    g.setColor(Color.black);
    g.fillRect(0,0,getWidth(),getHeight());
}

When I launch the program, I call this method.

However, I find that sometimes it works, and sometimes it doesn't. It's very odd. I also found out that when it doesn't work, the graphics object is NOT null, and the width and height are also correctly defined (from getWidth() and getHeight()).

Why would this sometimes work and sometimes not work?

What is the correct way to make a custom drawing on my JPanel at some point in the program? Is it correct to use getGraphics() as I am doing? My JPanel (at some point) has JComponents, but later on I remove those JComponents and do some custom graphics drawing. Why would this sometimes only work?

like image 422
CodeGuy Avatar asked Aug 16 '11 16:08

CodeGuy


People also ask

Can you draw on a JPanel?

Instead, in Swing, we usually draw on a JPanel. Turns out, you can draw on most Swing components, but are not advised to draw on top-level components like JFrame. The all-important technique of overriding paintComponent() (and, sometimes, repaint()): Like AWT, Swing does not maintain "bit-mapped memory".

What is a Java awt Graphics?

The Graphics class is the abstract super class for all graphics contexts which allow an application to draw onto components that can be realized on various devices, or onto off-screen images as well. A Graphics object encapsulates all state information required for the basic rendering operations that Java supports.


1 Answers

Don't get your Graphics object by calling getGraphics on a component such as a JPanel since the Graphics object obtained will not persist on the next repaint (which is likely the source of your problems).

Instead, consider doing all of your drawing in a BufferedImage, and then you can use getGraphics() to your heart's content. If you do this, don't forget to dispose of the Graphics object when you're done painting with it.

e.g.,

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class MyPaint extends JPanel {
   public static final int IMG_WIDTH = 400;
   public static final int IMG_HEIGHT = IMG_WIDTH;

   private BufferedImage image = new BufferedImage(IMG_WIDTH, IMG_HEIGHT,
            BufferedImage.TYPE_INT_ARGB);

   public MyPaint() {
      MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
      addMouseListener(myMouseAdapter);
      addMouseMotionListener(myMouseAdapter);
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      if (image != null) {
         g.drawImage(image, 0, 0, null);
      }
   }

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

   public void clearScreen() {
      Graphics g = image.getGraphics();
      g.setColor(Color.black);
      g.fillRect(0, 0, image.getWidth(), image.getHeight());
      g.dispose();
      repaint();
   }

   private class MyMouseAdapter extends MouseAdapter {
      // code to draw on the buffered image. 
      // Don't forget to call repaint() on the "this" JPanel
   }
}
like image 166
Hovercraft Full Of Eels Avatar answered Sep 30 '22 03:09

Hovercraft Full Of Eels