0

After calling a method with these two lines of code:

final Graphics canvasGraphics = screenCanvas.getGraphics();
canvasGraphics.fill3DRect(rectangleX, rectangleY, 500, 100, true);

The rectangle flashes when the program runs, and then disappears. However, when I put this same line in an anonymous inner class with my MouseListener:

screenCanvas.addMouseListener(new java.awt.event.MouseAdapter(){

    public void mousePressed(MouseEvent event){
        canvasGraphics.fill3DRect(rectangleX, rectangleY, 500, 100, true);
    }
}

The rectangle stays there. What is causing this behavior?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Enusi
  • 101
  • 1
  • 5
  • 1
    `screenCanvas.getGraphics();` - Don't do this. Create a `JPanel`, override it's `paintComponent` method, call `super.paintComponent(g)` inside and do your custom drawing there. – Lukas Rotter Feb 17 '16 at 16:32
  • So should I call drawPanel.paintComponent(screenCanvas.getGraphics()) where drawPanel is the overwritten JPanel? – Enusi Feb 17 '16 at 16:37
  • 1
    No, you should perform all painting inside the `paintComponent` method (you only need one panel) - No `getGraphics()` needed. Check out [this](https://docs.oracle.com/javase/tutorial/uiswing/painting/) for a full tutorial. Btw, I think the reason why the rectangle stays in your second snippet is because the `RepaintManager` doesn't automatically repaint the frame, so this way the rectangle stays there for a while. (Note how it also disappears when you resize the frame) – Lukas Rotter Feb 17 '16 at 16:41
  • Thank you so much, that really helps. – Enusi Feb 17 '16 at 16:45
  • The only reason to use a java.awt.Canvas is because you want to take direct control over the painting process – MadProgrammer Feb 17 '16 at 20:43
  • Swing and AWT/Canvas can have different painting process, see [this answer](http://stackoverflow.com/questions/35402007/having-issues-with-displays/35402391#35402391) and [this answer](http://stackoverflow.com/questions/12175174/paintcomponent-vs-paint-and-jpanel-vs-canvas-in-a-paintbrush-type-gui/12175819#12175819) for some details – MadProgrammer Feb 17 '16 at 20:50
  • If you want to use `java.awt.Canvas`, then you should be be using a [`BufferStrategy`](http://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferStrategy.html) and [BufferStrategy and BufferCapabilities](https://docs.oracle.com/javase/tutorial/extra/fullscreen/bufferstrategy.html) – MadProgrammer Feb 17 '16 at 20:51
  • You might also want to have a look at [Painting in AWT and Swing](http://www.oracle.com/technetwork/java/painting-140037.html) and [Performing Custom Painting](http://docs.oracle.com/javase/tutorial/uiswing/painting/) – MadProgrammer Feb 17 '16 at 21:23

1 Answers1

0

first you have to know that the Graphics of a JComponent is changed (repainted) on every change (resizing, minimizing, moving ...), and this happen inside the method public void paintComponent(Graphics g).

in the first scenario the two lines of code are executed just once and they have an effect (you noticed the flash), but the the Component is painted very often on every change, so when launching your application the canvasGraphics is filled by the two lines of code, but just after that the method paintComponent is called , so it repaints the Graphics again and you changes are lost.

in the second scenario you are not drawing on the Graphics directly, the Graphics is changed once the mouse is clicked so the paintComponent get executed when the program launches and the window is shown, once the mouse is Pressed inside the Canvas your reimplemented method is called and the Graphics is changed but this time the paintComponent method will not ommit your changes because nothing is happening to the element.

a solution is to reimplement the paintComponent method on the wanted element to be sure that your changes is performed each time the elements get repainted.

younes zeboudj
  • 856
  • 12
  • 22