我想在JPanel上绘制特定区域,就像这样(黑色区域是我想要重新绘制JPanel的地方):
下面的代码是我如何实现这一点。它跟随鼠标光标并在鼠标光标点处绘制一个圆圈。框架和面板的尺寸为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);
}
此代码的结果如下:
重绘在该区域之外进行重新粉刷。你能解释一下为什么会发生这种情况以及如何解决这个问题吗?
PS。当在mouseMoved中只调用单个重绘(100,100,100,100)时,代码完全有效。
谢谢
答案 0 :(得分:1)
我认为 Fast Snail 的解决方案通常是正确的答案。如果你有一个动态大小的电路板左右,你可以考虑只有当鼠标在所需的正方形内时才能画圆圈。
多次通话repaint
只占repaint
的更大区域,以包含您在repaint
的多次通话中指定的所有区域。
但是如果你有这个带有9个单元的小板,我认为可以快速解决你的情况,以免后续调用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
}
祝你好运。
答案 1 :(得分:0)
repaint()
仅标记要在EDT中重新绘制的组件。
后续调用不会改变任何内容。
使用坐标(矩形)调用repaint
标记仅在rect内重新绘制的组件。
后续调用只能更改(扩展)该矩形。
如果您希望clip
绘制到某个区域,则需要在paintComponent
方法中指定。