如何在 JPanel 上的其他 class 绘图中创建方法

How to create a method in other class drawing on JPanel

我的目标:创建一个 class 点的方法(代码在底部),它允许我绘制多个点(以及未来的线),所以它看起来像这样:

Point pointA = new Point(0,0);
Point pointB = new Point(10,20);
pointA.draw(); // or probably: pointA.draw(someSurface);
pointB.draw();

我从 tutorial 中获取了代码并对其进行了修改。

我在寻找答案时发现了很多类似的问题,但其中 none 个有我的案例的答案,或者我无法实现它。

正如您在下面看到的,我尝试在点 class 和表面 class 内部(注释代码)创建方法,但没有成功。

问题是什么,我应该在我的代码中修复什么?

主要:

public class Main {
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                BasicGraphics ex = new BasicGraphics();
                ex.setVisible(true);
                Point pointA = new Point(0,0);
                Point pointB = new Point(10,10);
                pointA.draw(ex.currentSurface);
                pointB.draw(ex.currentSurface);
            }
        });
    }
}

基本图形:

public class BasicGraphics extends JFrame {
    public Surface currentSurface;
    public BasicGraphics() {
        initUI();
    }
    private void initUI() {
        currentSurface=new Surface();
        add(currentSurface);
        setTitle("My points");
        setSize(100, 100);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

曲面:

class Surface extends JPanel {

    /*public void drawPoint(Graphics g, Point givenPoint) {
        //I want to represent points as little circles
        Ellipse2D circle = new Ellipse2D.Double(); 
        Graphics2D g2d = (Graphics2D) g;
        circle.setFrameFromCenter(givenPoint.x, givenPoint.y, 10,10);
        g2d.draw(circle);
    }*/
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
    }
}

积分:

public class Point {
    public double x;
    public double y;
    public Point(double newX, double newY){
        x=newX;
        y=newY;
    }

public void draw(Surface givenSurface){
    Graphics g = givenSurface.getGraphics();
    Ellipse2D circle = new Ellipse2D.Double();
    Graphics2D g2d = (Graphics2D) g;
    circle.setFrameFromCenter(x, y, 10,10);
    g2d.draw(circle);
    givenSurface.paint(g2d);
    //givenSurface.drawPoint(g2d,this);
    //givenSurface.repaint();
    }
}

编辑:解决方案,感谢 camickr。这不是我能想象的最优雅的方式,但它有效:

点中的绘制方法:

public void draw(Surface givenSurface){
        givenSurface.pointsList.add(this);
}

表面class:

class Surface extends JPanel {

    public ArrayList<Point> pointsList = new ArrayList<>();

    private void drawPoints(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        double diameter = 10;
        for (Point currentPoint : pointsList) {
            Ellipse2D circle = new Ellipse2D.Double(currentPoint.x - diameter / 2, currentPoint.y - diameter / 2, diameter, diameter);
            g2d.fill(circle);
        }
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        drawPoints(g);
    }

}

由于 paintComponent 方法将在 setVisible(true) 处被调用,但您在此之后绘制点,因此您必须重新绘制。见代码修改。

public class Main {
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                BasicGraphics ex = new BasicGraphics();
                ex.setVisible(true);
                Point pointA = new Point(0,0);
                Point pointB = new Point(10,10);
                pointA.draw(ex.currentSurface);
                pointB.draw(ex.currentSurface);
                ex.revalidate();
                ex.repaint();
            }
        });
    }
}

create a method of class Point (code at the bottom), that allows me to draw multiple points (and lines in the future).

所有的自定义绘画都需要在面板的paintComponent()方法中完成。因此,每次绘制面板时,都会重新绘制 points/lines。

所以如果你想绘制多个对象你需要:

  1. 创建要绘制的对象的 ArrayList
  2. 创建方法将对象添加到此列表
  3. 在 paintComponent() 方法中,您遍历列表并绘制每个对象。

查看 Custom Painting Approaches 中的 DrawOnCompont 示例。它显示了如何动态添加要绘制的矩形。