繁体   English   中英

java重绘多个区域

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM