создание JDialog с несколькими выбираемыми элементами изображения

Я пытаюсь создать фрейм JDialog, который будет иметь фоновое изображение и интерактивную JPanel над ним. В этом контексте JDialog будет представлять собой «боевое» поле, где можно будет выбирать и перемещать юниты. Игра основана на космосе, поэтому будет ArrayList кораблей и, возможно, планета для защиты.

Я смог переопределить paintComponent, чтобы нарисовать грубый круг, представляющий «планету», но не смог показать фоновое изображение JLabel. Затем я мог заставить фон JLabel показывать, но не мог видеть круги. В идеале я хочу заменить круги реальными изображениями для каждого типа корабля и уникальными для планет. Я открыт для других методов, кроме использования JDialog/JLayered/Customer JPanel, если есть лучший способ сделать это. Я работаю над этим больше часов, чем могу сосчитать.

Я создал JDialog, добавил JLayeredPane и установил в нем JLabel для фона. Я написал собственный класс, расширяющий JPanel, который будет добавлен в JLayeredPane над JLabel, который рисует круги для планеты и юнитов.

введите здесь описание изображения

Причина, по которой я выбрал 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);

person fakataha    schedule 27.04.2013    source источник


Ответы (2)


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.

person Gilbert Le Blanc    schedule 27.04.2013

Теперь у меня отображается фоновое изображение, а сверху нарисованы «корабль» и «планета». Я все еще пытаюсь определить, как выбрать событие мыши при нажатии на изображение.

Я добавил несколько новых переменных:

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

Теперь .... как подобрать события мыши в нарисованном изображении?

person fakataha    schedule 28.04.2013
comment
g3.drawImage(bgImage, 0, 0, null); должно быть g3.drawImage(bgImage, 0, 0, this); - person Andrew Thompson; 28.04.2013
comment
Теперь.... как получить события мыши в нарисованном изображении? Это должно быть в другом вопросе, если этот пост является ответом на этот вопрос. Если этот пост не является ответом на вопрос, информация должна быть отредактирована в вопросе . - person Andrew Thompson; 28.04.2013