2

i've seen a similar question, but i didn't get a proper solution, so here's my problem: (Coloring an area of BufferedImage)

i'm creating a BufferedImage, then i grab the graphics from this image, i'll paint a green rectangle on it and let it show within a JPanel... but surprise - it's not green, wo where is my error??

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class ViewPortTest {

    public static void main(String[] args) {
        new ViewPortTest().startUp();
    }


    private void startUp() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);        
        frame.add(new TestPanel() );
        frame.pack();       
        frame.setVisible(true);
    }

    private class TestPanel extends JPanel{

        private static final long serialVersionUID = 1L;
        private int myWidth = 256;
        private int myHeight = 156;     
        private BufferedImage img;      

        public TestPanel() {
            super();        
            setPreferredSize(new Dimension(myWidth, myHeight) );            
            img = new BufferedImage(myWidth, myHeight, BufferedImage.TYPE_4BYTE_ABGR);
            img.createGraphics();                   
            img.getGraphics().setColor(Color.GREEN);
            img.getGraphics().fillRect(0, 0, 256, 256);         
            img.getGraphics().dispose();
        }

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

what comes out is this:

not green screen

so - where is my green rectangle???

Community
  • 1
  • 1
Martin Frank
  • 3,445
  • 1
  • 27
  • 47
  • Why do you `dispose()` the Graphics ? You still need it on painting. – PeterMmm Aug 06 '14 at 09:57
  • Hi Peter, it won't make any difference - i read about that 'hint' to dispose the graphics in another SOF-article , but it won't make any difference, have a try on your own... – Martin Frank Aug 06 '14 at 09:58
  • Overriding `paintComponent` is not a good idea. May help: http://stackoverflow.com/questions/15544549/how-does-paintcomponent-work – PeterMmm Aug 06 '14 at 09:59
  • Hi Peter, the image is drawn indeed, it's not a matter of repaint... but it's white colored not green.... – Martin Frank Aug 06 '14 at 10:01
  • Hi Peter, it makes no difference if you paintComponent(Graphics gr) or simply paint(Graphics gr) – Martin Frank Aug 06 '14 at 10:03
  • Hello Peter, thanks again for bringing in so much passion... even if you may not have helped me directly, you provided aid when it was required! – Martin Frank Aug 06 '14 at 10:12

3 Answers3

2

The problem is the multiple calls to getGraphics(). It is creating multiple Graphics objects. This is essentially an alias for createGraphics(). See BufferedImage#getGraphics. A simple fix would be to store the Graphics2D object created by calling createGraphics() and make all of your calls on that object:

Graphics2D g = img.createGraphics();                   
g.setColor(Color.GREEN);
g.fillRect(0, 0, 256, 256);         
g.dispose();
Marc Baumbach
  • 10,323
  • 2
  • 30
  • 45
  • so i'm very confused - what's the purpose of createGraphics() and getGraphics() maybe you can add a slight explanation on why my Graphics would be reCreated every time i ask for it? – Martin Frank Aug 06 '14 at 10:07
  • The docs explain the reasoning for `getGraphics`, it's basically there for backwards compatibility. It was also a poor name for a method because it doesn't return the same object every time it is called (Thus your confusion). Basically, you can treat it as deprecated, since `createGraphics` provides a better interface and is more explicitly named. – Marc Baumbach Aug 06 '14 at 10:08
  • a @depricated would have helped me very much... thanks again for that explanation and thanks, that you do have the same understanding for getter/setter... – Martin Frank Aug 06 '14 at 10:10
1

Because createGraphics() always returns a new Graphics2D context. So you set the green color on one context, and you fill a rectange using another which does not know about the green color you set on another context.

Try this:

Graphics2d g = img.createGraphics();                   
g.setColor(Color.GREEN);
g.fillRect(0, 0, 256, 256);         
g.dispose();
icza
  • 389,944
  • 63
  • 907
  • 827
1

Simple problem with Graphics instance:

  Graphics2D createGraphics = img.createGraphics();                   
  createGraphics.setColor(Color.GREEN);
  createGraphics.fillRect(0, 0, 256, 256);         
  createGraphics.dispose();
alex2410
  • 10,904
  • 3
  • 25
  • 41