![](/img/trans.png)
[英]Does java consolidate multiple repaint() calls into a single repaint()?
[英]java repaint multiple area
我想在 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);
}
这段代码的结果是这样的:
它在要重新粉刷的区域之外重新粉刷。 你能解释一下为什么会发生这种情况以及如何解决这个问题吗?
附注。 当在 mouseMoved 中只调用一次 repaint(100,100,100,100) 时,代码完全运行良好。
谢谢
我认为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
}
祝你好运。
repaint()
仅标记要在 EDT 中重绘的组件。 后续调用不会改变任何东西。
使用坐标(矩形)调用repaint
仅在矩形内标记要重绘的组件。 后续调用只能更改(扩展)该矩形。
如果要将绘图clip
到某个区域,则需要在您的paintComponent
方法中指定。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.