【问题标题】:creating a JDialog with multiple, selectable image items创建具有多个可选图像项的 JDialog
【发布时间】:2013-04-27 06:07:21
【问题描述】:

我正在尝试创建一个 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);

【问题讨论】:

    标签: java swing paintcomponent jdialog jlayeredpane


    【解决方案1】:

    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 上的鼠标点击。

    【讨论】:

      【解决方案2】:

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

      我添加了一些新变量:

          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);
          }
      }
      

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

      【讨论】:

      • g3.drawImage(bgImage, 0, 0, null); 应该是g3.drawImage(bgImage, 0, 0, this);
      • “现在......如何在绘制的图像中获取鼠标事件?” 如果这篇文章是这个问题的答案,那应该是另一个问题。如果此帖子不是问题的答案,则信息应为edited into the question
      猜你喜欢
      • 1970-01-01
      • 2016-08-08
      • 1970-01-01
      • 1970-01-01
      • 2018-08-11
      • 1970-01-01
      • 2013-04-29
      • 1970-01-01
      • 2018-03-31
      相关资源
      最近更新 更多