我如何 represent/work 将 Ellipse2D 和 Rectangle 作为一个形状?

How do I represent/work with an Ellipse2D and a Rectangle as one shape?

我想画一个简单的简笔画。这需要一个圆形和一些矩形。我可以通过许多 g2d.fill() 调用分别绘制头部、躯干等。但是,如果可能的话,我希望能够将其表示为一个形状并通过一次填充调用绘制它。此外,如果我想将简笔画向右移动 10 个像素,我目前必须更改椭圆上的 x 坐标 + 10 和矩形上的 x 坐标 + 10 等等。我希望能够更改单个 x 坐标,然后将所有单独的组件移开。

我怎样才能做到这一点?

代码:

public class StickFigure{
    Ellipse2D head = new Ellipse2D.Double(0, 0, 100, 100);
    Rectangle torso = new Rectangle(100, 100, 50, 110); 
    Rectangle rightArm;
    ...
}

我要做的事情:

g2d.fill(sf.head);
g2d.fill(sf.torso);
...

我想做的事情:

g2d.fill(sf.figure) //figure being a shape which includes both head and torso

我要做的事情:

     sf.head.x = 3;
     sf.head.y = 4;
     sf.torso.x = 3;
     sf.torso.y = 4;
     g2d.fill(sf.head);
     g2d.fill(sf.torso);
     ...

我想做的事情:

sf.figure.x = 3; //which shifts both the head and the torso
sf.figure.y = 4; // ^^
g2d.fill(sf.figure);

您可以创建一个 BufferedImage 来表示您的简笔画。然后将矩形和省略号绘制到 BufferedImage 上。

BufferedImage bi = new BufferedImage(...);
Graphics2D g2d = bi.getGraphics();
g2d.fillOval(...);
g2d.fillRect(...);

BufferedImage 将是您在构造 class 时创建的实例变量。然后你可以在你的 paintComponent() 方法中绘制 BufferedImage。

graphics.drawImage(bi, ...);

然后,无论何时您想要移动图像,只需更改 drawImage(...) 方法中的 x/y 值即可。

组成简笔画的不同形状可以变成一个 Area

class StickFigure {

    private Area stickFigure;
    private Color color;

    StickFigure(Color color, int x) {
        this.color = color;
        stickFigure = new Area(new Ellipse2D.Double(x, 0, 100, 100));
        stickFigure.add(new Area(new Rectangle(x+25, 100, 50, 110)));
    }

    public Area getStickFigure() {
        return stickFigure;
    }

    public void draw(Graphics2D g) {
        g.setColor(color);
        g.fill(stickFigure);
    }
}

MCVE

import java.awt.*;
import java.awt.geom.*;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.border.EmptyBorder;

public class StickFigurePainter {

    private JComponent ui = null;

    StickFigurePainter() {
        initUI();
    }

    public void initUI() {
        if (ui != null) {
            return;
        }

        ui = new JPanel(new BorderLayout(4, 4));
        ui.setBorder(new EmptyBorder(4, 4, 4, 4));

        ArrayList<StickFigure> list = new ArrayList<StickFigure>();
        list.add(new StickFigure(Color.RED, 0));
        list.add(new StickFigure(Color.GREEN, 110));
        list.add(new StickFigure(Color.BLUE, 220));
        
        ui.add(new StickCanvas(list));
    }

    public JComponent getUI() {
        return ui;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception useDefault) {
                }
                StickFigurePainter o = new StickFigurePainter();

                JFrame f = new JFrame(o.getClass().getSimpleName());
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                f.setLocationByPlatform(true);

                f.setContentPane(o.getUI());
                f.pack();
                f.setMinimumSize(f.getSize());

                f.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

class StickCanvas extends JPanel {

    private ArrayList<StickFigure> stickFigures;

    StickCanvas(ArrayList<StickFigure> stickFigures) {
        this.stickFigures = stickFigures;
    }

    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        for (StickFigure stickFigure : stickFigures) {
            stickFigure.draw(g2);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        Area area = new Area();
        for (StickFigure stickFigure : stickFigures) {
            area.add(stickFigure.getStickFigure());
        }
        return area.getBounds().getSize();
    }
}

class StickFigure {

    private Area stickFigure;
    private Color color;

    StickFigure(Color color, int x) {
        this.color = color;
        stickFigure = new Area(new Ellipse2D.Double(x, 0, 100, 100));
        stickFigure.add(new Area(new Rectangle(x+25, 100, 50, 110)));
    }

    public Area getStickFigure() {
        return stickFigure;
    }

    public void draw(Graphics2D g) {
        g.setColor(color);
        g.fill(stickFigure);
    }
}