Reputation: 79
On the way of trying to understand repaint() and paintComponent (), I saw these code on http://docs.oracle.com/javase/tutorial/uiswing/painting/step3.html:
import javax.swing.SwingUtilities;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseMotionAdapter;
public class SwingPaintDemo3 {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
System.out.println("Created GUI on EDT? "+
SwingUtilities.isEventDispatchThread());
JFrame f = new JFrame("Swing Paint Demo");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new MyPanel());
f.pack();
f.setVisible(true);
}
}
class MyPanel extends JPanel {
private int squareX = 50;
private int squareY = 50;
private int squareW = 20;
private int squareH = 20;
public MyPanel() {
setBorder(BorderFactory.createLineBorder(Color.black));
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
moveSquare(e.getX(),e.getY());
}
});
addMouseMotionListener(new MouseAdapter() {
public void mouseDragged(MouseEvent e) {
moveSquare(e.getX(),e.getY());
}
});
}
private void moveSquare(int x, int y) {
int OFFSET = 1;
if ((squareX!=x) || (squareY!=y)) {
repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
squareX=x;
squareY=y;
repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
}
}
public Dimension getPreferredSize() {
return new Dimension(250,200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString("This is my custom Panel!",10,20);
g.setColor(Color.RED);
g.fillRect(squareX,squareY,squareW,squareH);
g.setColor(Color.BLACK);
g.drawRect(squareX,squareY,squareW,squareH);
}
}
The question I have with these code is I don't understand the line "repaint(squareX, squareY, squareW+offset,squareH+offset". First, what I understand about repaint() is it basically just calls paint(Graphics g) or paintComponent(Graphics g), which you obviously can't call it like a normal program since you can't actually input a graphics, like input a int or a string. However, this program's paintComponent() not have any extra input(like perhaps it would have paintComponent(Graphics g, int squareX, int squareY, int squareW, int squareH)), so where does the input given to repaint go...? What is it used for?
Upvotes: 0
Views: 164
Reputation: 205875
The example cited invokes repaint(int x, int y, int width, int height)
for rendering efficiency in the loop implicit in the mouse handler. The implementation of this variation of repaint()
asks the RepaintManager
to add the region bounded by the coordinates to those of other "components that should be refreshed." The update region is the union for the two re-painted rectangles.
As noted here, this can result in a technical violation of the single-thread rule common to GUI frameworks such as Swing. Because instances of Runnable
are continually posted to the EventQueue
, the risk of a failed read is small. Profile both approaches (exercise 3) to evaluate the benefit vs. risk.
Upvotes: 1
Reputation: 324207
I don't understand the line
"repaint(squareX, squareY, squareW+offset,squareH+offset".
That code is used to repaint a small rectangular are of the panel, instead of repainting the whole panel. Painting a small area will obviously be more efficient than painting a small area.
Also, that statement is invoked twice. The repaint() method invokes the RepaintManager
with a paint request to repaint two rectangular area. The RepaintManager
will combine the two requests into one paint request which again will make the code more efficient.
So the first statement is used to clear the painting of the Rectangle at its current location. Then the x/y location of the Rectangle is changed and a second repaint() request is made so the Rectangle can be repainted at its new location.
Try the code without the first repaint(...) statement and you will see that the original Rectangle is not completely cleared so you get traces of the old Rectangle.
Upvotes: 1
Reputation: 1796
Here is something that can help you with that.
public void repaint(int x, int y, int width, int height) Repaints the specified rectangle of this component.
Just calling a normal repaint()
will just repaint the component, but using these paramteres you are repainting a specific rectangle of that component.
Upvotes: 0