Reputation: 13
I want to draw specific area on JPanel, like this (black area is where I want JPanel to be repainted):
Below code is how I implemented this. It follows mouse cursor and draws a circle at the mouse cursor point. The size of frame and panel is 300*300.
public class MiniGraphicTest extends JPanel{
private static final long serialVersionUID = 1L;
public int x,y;
public MiniGraphicTest() {
super();
x = -1;
y = -1;
addMouseMotionListener(new MouseMotionAdapter(){
@Override
public void mouseMoved(MouseEvent m){
x = m.getX()-25;
y = m.getY()-25;
repaint(100,100,100,100);
repaint(200,200,100,100);
}
});
}
protected void paintComponent(Graphics g){
super.paintComponent(g);
//////////////////////
//DO NOT MODIFY HERE//
//////////////////////
//Draw gridline
int width = this.getWidth();
int height = this.getHeight();
g.setColor(Color.BLACK);
for(int i=100;i<width;i+=100){
g.drawLine(i, 0, i, height);
}
for(int i=100;i<height;i+=100){
g.drawLine(0, i, width, i);
}
//////////////////////
//put test code here//
//////////////////////
if(x == -1&&y==-1) return;//initially draw nothing
g.fillOval(x, y, 50, 50);
}
}//main function is just showing the panel. nothing special
public static void main(String[] args) {
JFrame jf = new JFrame("Test");
MiniGraphicTest test = new MiniGraphicTest();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
test.setPreferredSize(new Dimension(300, 300));
jf.setResizable(false);
jf.add(test);
jf.pack();
jf.setVisible(true);
}
The result of this code is like this :
It repaints outside of the area to be repainted. Can you explain me why this happened and how to solve this?
PS. The code completely works well when only single repaint(100,100,100,100) is called in the mouseMoved.
Thank you
Upvotes: 1
Views: 226
Reputation: 4377
I think Fast Snail's solution is is the right answer in general. If you have a dynamic situation with dynamic size of the board or so, you may consider draw circle only if mouse is inside the required squares as recommended.
Multiple calling repaint
only makes a bigger area of repaint
to include all the area's you specified in the multiple calls of repaint
.
But if you have this little board with 9 cells, I think there is a quick fix for your situation in order not to make subsequent calls for repaint
:
public class MiniGraphicTest extends JPanel {
private static final long serialVersionUID = 1L;
public int x, y;
boolean flag;
public MiniGraphicTest() {
super();
x = -1;
y = -1;
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent m) {
x = m.getX() - 25;
y = m.getY() - 25;
if(flag) {
repaint(100, 100, 100, 100);
} else {
repaint(200, 200, 100, 100);
}
flag = !flag;
}
});
}
// Other codes of yours
}
Good Luck.
Upvotes: 1
Reputation: 1032
repaint()
only marks the component to be repainted in EDT.
Subsequent calls not changes anything.
Calling repaint
with coordinates (rectangle) mark the component to be repainted only inside the rect.
Subsequent calls can only change (extend) that rect.
If you want to clip
drawing to some area, you need to specify that in your paintComponent
method.
Upvotes: 0