如何在JFrame中重叠图像

时间:2018-05-29 02:09:21

标签: java swing

我无法在JFrame中获得两个彼此重叠的图像。我尝试过使用一个JPanel和两个JPanel,但没有任何效果。我已经考虑过试用JLayeredPane(s),但无济于事。我有很多可以互动的课程,所以我不知道如果显示我的代码会有所帮助,但这是我未完全实现的代码:

import javax.swing.JLabel;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLayeredPane;
import javax.swing.ImageIcon;
import java.awt.Graphics2D;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import java.io.IOException;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;

public class MazeDisplay implements KeyListener
{
static JFrame window;
static JPanel backPanel, userPanel;
JLabel user, cpu, maze1, maze2;
User u;

public MazeDisplay(String x, Cell[][] maize1, Cell[][] maize2) throws IOException
{
    maze1 = new JLabel(new ImageIcon(createMazeImage(maize1)));
    maze2 = new JLabel(new ImageIcon(createMazeImage(maize2)));
    user = new JLabel(new ImageIcon("user.png"));
    cpu = new JLabel(new ImageIcon("cpu.png"));
    u = new User(maize1);
    window = new JFrame(x);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setBounds(400, 400, 986, 509);
    backPanel = (JPanel) window.getContentPane();
    backPanel.setLayout(null);
    maze1.setBounds(0, 0, 480, 480);
    maze2.setBounds(500, 0, 480, 480);
    backPanel.add(maze1);
    backPanel.add(maze2);
    userPanel = new JPanel(null);
    user.setBounds(0, 0, 30, 30);
    cpu.setBounds(500, 0, 30, 30);
    userPanel.add(user);
    userPanel.add(cpu);
    window.add(userPanel);
    window.setResizable(false);
    window.setVisible(true);
}

public void keyPressed(KeyEvent e) {}

public void keyReleased(KeyEvent e) {}

public void keyTyped(KeyEvent e) {}

public boolean isLegal(int dir)
{
    boolean ret = false; Cell[][] maze = u.getMaize();
    if(0 <= u.xPos() && u.xPos() < maze.length && 0 <= u.yPos() && u.yPos() < maze.length)
    {
        if(dir == 0) ret = (maze[u.xPos()][u.yPos()].isOpen(dir) && maze[u.xPos()][u.yPos()-1].isOpenO(dir));
        else if(dir == 1) ret = (maze[u.xPos()][u.yPos()].isOpen(dir) && maze[u.xPos()+1][u.yPos()].isOpenO(dir));
        else if(dir == 2) ret = (maze[u.xPos()][u.yPos()].isOpen(dir) && maze[u.xPos()][u.yPos()+1].isOpenO(dir));
        else if(dir == 3) ret = (maze[u.xPos()][u.yPos()].isOpen(dir) && maze[u.xPos()-1][u.yPos()].isOpenO(dir));
    }
    return ret;
}

public static BufferedImage createMazeImage(Cell[][] maze) throws IOException
{
    BufferedImage[][] iMaze = new BufferedImage[maze.length][maze.length];
    for(int i = 0; i < iMaze.length; i++)
        for(int j = 0; j < iMaze.length; j++)
        {
            String cellDir = maze[i][j] + ".png";
            iMaze[i][j] = new BufferedImage(30, 30, BufferedImage.TYPE_INT_RGB);
            Graphics2D icon = iMaze[i][j].createGraphics();
            icon.drawImage(ImageIO.read(new File(cellDir)), 0, 0, null);
        }

    int xOff = 0, yOff = 0;
    BufferedImage mazeImage = new BufferedImage(maze.length * 30, maze.length * 30, BufferedImage.TYPE_INT_RGB);
    Graphics2D g = mazeImage.createGraphics();

    for(int r = 0; r < iMaze.length; r++)
    {
        for(int c = 0; c < iMaze.length; c++)
        {
            g.drawImage(iMaze[r][c], xOff, yOff, null);
            yOff += 30;
        }
        yOff = 0;
        xOff += 30;
    }
    return mazeImage;
}

public static void main(String[] args) throws IOException
{
    MazeGen g = new MazeGen(16);
    MazeGen h = new MazeGen(16);
    MazeDisplay m = new MazeDisplay("Maze Game", g.getMaze(), h.getMaze());
}
}
编辑:我为这么模糊而道歉,当时我非常疲惫和烦躁。虽然我很模糊,但非常感谢帮助,因为我使用GridPagLayout正如MadProgrammer建议的那样。

2 个答案:

答案 0 :(得分:1)

所以,这是一个非常快速的例子。

它使用GridBagLayout允许两个组件同时占用相同的空间。然后使用简单的Timer更新播放器的位置,以证明基本概念有效。

It's a mea, Mario

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    JFrame frame = new JFrame();
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });
    }

    public class TestPane extends JPanel {

        private JLabel player;

        public TestPane() throws IOException {
            BufferedImage tileImg = ImageIO.read(getClass().getResource("Tile.jpg"));
            BufferedImage playerImg = ImageIO.read(getClass().getResource("Mario.png"));
            Icon tileIcon = new ImageIcon(tileImg);
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            player = new JLabel(new ImageIcon(playerImg));
            gbc.gridx = 0;
            gbc.gridy = 0;
            add(player, gbc);
            for (int row = 0; row < 10; row++) {
                for (int col = 0; col < 10; col++) {
                    gbc.gridx = col;
                    gbc.gridy = row;
                    add(new JLabel(tileIcon), gbc);
                }
            }

            Timer timer = new Timer(500, new ActionListener() {
                private int x = 0;
                private int y = 0;
                @Override
                public void actionPerformed(ActionEvent e) {
                    x++;
                    if (x > 9) {
                        x = 0;
                        y++;
                    }
                    if (y > 9) {
                        y = 0;
                    }
                    GridBagLayout layout = (GridBagLayout) getLayout();
                    GridBagConstraints gbc = layout.getConstraints(player);
                    gbc.gridx = x;
                    gbc.gridy = y;
                    layout.setConstraints(player, gbc);
                    revalidate();
                }
            });
            timer.start();
        }

    }

}

由于API的工作方式,组件以LIFO顺序显示,这意味着必须首先添加播放器组件。

您还可以将其与JLayeredPane结合使用,这样可以控制组件的z排序

声明...

虽然此解决方案确实有效,但维护或管理并不容易。更好的解决方案是遵循自定义绘画路线,这将使您更好地控制绘画内容以及何时何地。

查看Performing Custom Painting了解一些基本信息

答案 1 :(得分:0)

如果实施得很好,分层窗格应该可以正常工作,这里有更多关于它的信息,如何使用它以及它的一些示例和代码:

https://docs.oracle.com/javase/tutorial/uiswing/components/layeredpane.html