I’m teaching myself AWT/Swing using an Oracle tutorial. There’s a section a don’t fully understand.
It concerns an application that creates dynamic graphics using the Graphics class. I understand that the code that creates graphics should be put in a “paintComponent” method of a (descendant of a) JPanel class. And that when you want to change something on this panel outside “paintComponent”, you have to call the “repaint” method, that somehow causes “paintComponent” to be invoked.
This code indeed works. However, I don’t understand why. The explanation at the Oracle site is the following. “Because we are manually setting the clip, our moveSquare method invokes the repaint method not once, but twice. The first invocation tells Swing to repaint the area of the component where the square previously was (the inherited behavior uses the UI Delegate to fill that area with the current background color.) The second invocation paints the area of the component where the square currently is.”
However, what I don’t understand: when repaint is first invoked, squareX and squareY still have their old values. If the invocation of repaint simply causes an invocation of paintComponent, then paintComponent should draw a red square at (squareX, squareY). Just like the second invocation of repaint causes paintComponent to draw a red suare at the new values of (squareX, squareY). Instead, the first invocation results in the red square being wiped out by the background color.
So apparently, the first invocation of repaint does not simply cause an invocation of paintComponent. What does it do?
The repaint() method is just a suggestion to repaint the component. It does not mean that the paintComponent() method is called every time. In fact to make painting more efficient the RepaintManager will handle the repaint() request and merge multiple requests into one call to paintComponent. In this case the two calls to repaint happen immediately after one another so the request are in fact merged into one.
Try adding the following line of code to the paintComponent() method:
Then click the mouse close to the square and far away from the square and you will see that the Rectangle size changes based on the old/new location.
So then what happens is that the super.paintComponent() will clear the entire clipped area and then the square will be painted at its new location.
Just for fun also comment out the super.paintComponent() method to see what happens.