1

我正在尝试创建一个 JDialog 框架,该框架将具有背景图像和上面的交互式 JPanel。在这种情况下,JDialog 将代表一个“战斗”领域,可以在其中选择和移动单位。该游戏是基于空间的,因此将有一个 ArrayList 船舶和可能要防御的行星对象。

我已经能够覆盖paintComponent 来绘制一个代表“行星”的粗略圆圈,但无法显示背景JLabel 图像。然后我可以让背景 JLabel 显示但看不到圆圈。理想情况下,我想用每种船类型的实际图像和行星的独特图像替换圆圈。如果有更好的方法来实现这一点,我愿意接受除使用此 JDialog/JLayered/Customer JPanel 之外的其他方法。我已经为此工作了比我数不清的时间。

我创建了一个 JDialog,添加了一个 JLayeredPane 并在其中设置了一个 JLabel 作为背景。我编写了一个扩展 JPanel 的自定义类,该类将添加到 JLabel 上方的 JLayeredPane 中,它为行星和单位绘制圆圈。

在此处输入图像描述

我选择 JPanel 的原因是我可以检查鼠标事件以确定玩家选择的是什么(添加资源的星球)或一艘船(用于移动和攻击)。

对于自定义 JPanel,我编写了这个简单的扩展:

public class SectorPnl extends javax.swing.JPanel implements MouseInputListener, ActionListener {

private int                 circleY, circleX, circleRadius;
private Sector              sector;
private Shape               planetShape;
private Shape               shipShape;
private Ship                ship;
private Planet              planet;
private Invasion            inv;
private ArrayList<ShipType> shipBuild;

public SectorPnl(Sector sector, Invasion inv)
{
    initComponents();

    this.sector = sector;
    this.inv = inv;
    this.planet = sector.getPlanet();
    shipBuild = new ArrayList();

    Timer update = new Timer(28, this);
    update.start();

    if ( sector.hasPlanet() )
    {
        circleRadius = (int) sector.getPlanet().getPlanetRadius();
        circleX = (int) sector.getPlanet().getPositionX();
        circleY = (int) sector.getPlanet().getPositionY();
        planetShape = new Ellipse2D.Double(circleX, circleY, circleRadius,
                circleRadius);
    }
}

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

    Graphics2D g2 = (Graphics2D) g;

    if ( planetShape != null)
    {
        g2.setColor(Color.red);
        g2.fill(planetShape);
        g2.draw(planetShape);
    }
    if ( shipShape != null )
    {
        g2.setColor(Color.white);
        g2.fill(shipShape);
        g2.draw(shipShape);
    }
} 

这是将其添加到 JDialog 的行:

  sectorDlg.setTitle(sector.getName());

  sectorDlg.setVisible(true);
  sectorDlg.setSize(800,800); 

  SectorPnl sectorPnl = new SectorPnl(sector, inv);
  sectorPnl.addMouseListener(sectorPnl);
  sectorPnl.addMouseMotionListener(sectorPnl);

  sectorLayer.setLayer(sectorPnl, 100);
  sectorLayer.setBounds(0, 0, 800, 800);
4

2 回答 2

0

JLabel 可以同时显示图标和文本,但我认为您必须指定图标和文本的相对位置。

ImageIcon icon = createImageIcon("images/middle.gif");
. . .
label1 = new JLabel("Image and Text",
                    icon,
                    JLabel.CENTER);
//Set the position of the text, relative to the icon:
label1.setVerticalTextPosition(JLabel.BOTTOM);
label1.setHorizontalTextPosition(JLabel.CENTER);

这取自 Oracle 的如何使用标签

我不知道如果您尝试设置背景和前景色会发生什么。

我认为如果您使用 JPanel 作为画布,并在您想要的位置绘制图标和文本,您会更好。您可以处理 JPanel 上的鼠标点击。

于 2013-04-27T11:58:58.570 回答
0

我现在显示了背景图像,并在顶部绘制了“船”和“行星”。我仍在尝试确定单击图像时如何选择鼠标事件。

我添加了一些新变量:

    private Image               bgImage;
    private Image               shipImage;

为了纠正背景问题,我在 initComponents(); 之后添加了这些行。

    ImageIcon ii = new ImageIcon(this.getClass().getResource("sector_Bg1.png"));
    bgImage = ii.getImage();

我更改了我的paintComponent 方法以添加船舶图标(以.png 或.jpg 格式)并绘制它们。

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

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

    g3.drawImage(bgImage, 0, 0, null);

    if ( planetShape != null)
    {
        g2.setColor(Color.red);
        g2.fill(planetShape);
        g2.draw(planetShape);
    }
    for ( Ship s : sector.getShips() )
    {
        ImageIcon si = new ImageIcon(this.getClass().getResource("isd.png"));
        shipImage = si.getImage();
        g3.drawImage(shipImage, (circleX + shipImage.getHeight(null)), circleY, null);
    }
}

现在....如何在绘制的图像中获取鼠标事件?

于 2013-04-28T02:55:49.487 回答