JFrame 中心的绘图圆在 `repaint()` 后不更新

Drawing circle at centre of JFrame doesn't update after `repaint()`

我正在编写一个程序,该程序涉及创建一个 JFrame 并使用图形 class 中的 drawOval() 在其中绘制一个圆圈。我遇到了一个问题,我试图在 JFrame 的中心创建一个点,然后用这个点作为圆的 x 和 y 坐标绘制我的圆。到目前为止,这是我的代码:

import java.awt.Graphics;
import javax.swing.JFrame;
import java.awt.event.*;
import java.awt.geom.Point2D;
import java.awt.Point;

class MouseJFrameMotion  extends JFrame implements MouseMotionListener{

    int circleXcenter;
    int circleYcenter;  
    int circleRadius = 50;
    boolean show = false;

    public MouseJFrameMotion(){       
        addMouseMotionListener(this);
    }

    public void paint(Graphics g){     

        super.paint(g);

        if(show){
            g.drawOval(circleXcenter,circleYcenter, circleRadius*2,circleRadius*2);
        }
    }

    public void mouseDragged(MouseEvent e){

    }

    Point frameCenter = new Point((this.getWidth()/2), (this.getHeight()/2));

    public void mouseMoved(MouseEvent e){
        int xLocation = e.getX();
        int yLocation = e.getY();   
        show = true;
        circleXcenter = (int) frameCenter.getX();
        circleYcenter = (int) frameCenter.getY();
        repaint();
    }
}

public class GrowingCircle {

    public static void main(String[] args) {
        MouseJFrameMotion  myMouseJFrame = new MouseJFrameMotion();
        myMouseJFrame.setSize(500, 500);
        myMouseJFrame.setVisible(true);
    }
}

正如您在 main() 函数中看到的那样,我将 JFrame 的大小设置为 500x500。但是,当绘制圆时,它的 x 和 y 坐标是 (0,0),而我期望它们是 (250, 250) 基于 Point frameCenter 在调用 repaint() 之后。我哪里错了?

我认为您同时需要 repaint() 和 revalidate() 方法

在构建class MouseJFrameMotion 时,定义了变量frameCenter 并将宽度和高度设置为0,它永远不会改变。所以你可以做的就是在画图的时候计算一下画框的中心。

public void mouseMoved(MouseEvent e) {
    int xLocation = e.getX();
    int yLocation = e.getY();
    show = true;
    Point frameCenter = new Point((this.getWidth() / 2), (this.getHeight() / 2));
    circleXcenter = (int) frameCenter.getX();
    circleYcenter = (int) frameCenter.getY();
    repaint();
}

所以有两件事...

  1. 不要覆盖 JFramepaint,在用户和框架表面之间存在 JRootPanecontentPane 和其他可能干扰绘画的组件.相反,使用 JPanel 并覆盖其 paintComponent 方法
  2. 在计算 Point frameCenter = new Point((this.getWidth()/2), (this.getHeight()/2)); 时,框架的大小为 0x0,您需要在绘制圆之前重新计算 frameCenter。何时执行此操作取决于您希望更改的动态程度