-1

我在将多个图像从对象绘制到自​​定义 JPanel 时遇到问题。我已经能够成功地在 JPanel 上绘制一个对象的图像表示。我相信,添加更多对象只会在另一个图像之上绘制,因为它们使用相同的 Graphics2D 对象。

所以我决定创建一个包含 Shapes、Image 和 Object 的自定义 JComponent,但不幸的是它并没有更好地工作。我的想法是这将允许 JPanel 为每个对象使用一个 for 循环并创建一个新的 Graphics2D 对象来绘制。

这是我正在编程的游戏,仅供参考。我试图绘制的对象是屏幕上需要操作的单位。

public class ShipGraphic extends JComponent{

private Shape       shipShape, combatShape;
private Image       shipImage;
private ImageIcon   si;
private int         shipX = 0, shipY = 0, shipW, shipH, combatH, combatW, combatR;
private Ship        ship;

public ShipGraphic(Ship ship)
{
    this.ship = ship;
    setImageIcon();
    shipImage = si.getImage();
    shipW = shipImage.getWidth(null);
    shipH = shipImage.getHeight(null);
    combatH = shipH * 2;
    combatW = shipW * 2;
    combatR = -(shipW * 2);
    shipShape = new Rectangle2D.Double(shipX, shipY, shipW, shipH);
    combatShape = new Ellipse2D.Double(combatR, combatR, combatW, combatH);
}

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

    Graphics2D g2 = (Graphics2D) g;
    Graphics2D g3 = (Graphics2D) g;
    Graphics2D g4 = (Graphics2D) g;

    g2.drawImage(shipImage, shipX, shipY, null);
    g3.setColor(new Color(0,0,0,0));
    g3.drawRect(shipX, shipY, shipW, shipH);
    g4.draw(combatShape);
}

ShipGraphic 使用 Rectangle 来检查用户是否单击了 Image,并将使用 Circle 来确定它是否与另一个矩形相交以进行战斗。这两个形状在 Image 下绘制为不透明的。

然后自定义 JPanel 使用这个 for 循环将它们添加到面板中:

    for ( Ship s : sector.getShips() )
    {
        ShipGraphic ship = new ShipGraphic(s);
    }
4

1 回答 1

2

我相信,添加更多对象只会在另一个图像之上绘制,因为它们使用相同的 Graphics2D 对象。

问题不是因为您使用相同的 Graphic 对象。给定帧上的所有 Swing 组件都使用相同的 Graphics 对象进行绘制。如果它们相互叠加,那是因为您没有为每个对象指定正确的 x/y 位置。

所以我决定创建一个包含 Shapes 的自定义 JComponent

这是一个很好的方法。但是,在这种情况下,您将始终在组件的位置 (0, 0) 处绘制对象。然后,您将通过调用组件来定位每个setLocation(...)组件。

您还需要覆盖组件的 getPreferredSize() 方法,以确保它返回组件的适当大小。

您发布的示例代码有输入错误。去掉 super.paintComponents(g) 上的“s”。

于 2013-04-30T01:51:19.873 回答