创建具有多个可选图像项的JDialog

时间:2013-04-27 06:07:22

标签: java swing paintcomponent jdialog jlayeredpane

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

我已经能够覆盖paintComponent来绘制一个代表“行星”的粗圆,但无法显示背景JLabel图像。然后我可以得到背景JLabel显示但看不到圆圈。理想情况下,我想用每种船型的实际图像替换圆圈,并且对于行星是唯一的。如果有更好的方法可以实现这一点,那么我可以使用其他方法,而不是使用这个JDialog / JLayered / Customer JPanel。我一直在研究这个问题的时间超过了我的计算时间。

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

enter image description here

我选择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);

2 个答案:

答案 0 :(得分: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的How to use labels

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

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

答案 1 :(得分: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);
    }
}

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