我无法在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建议的那样。
答案 0 :(得分:1)
所以,这是一个非常快速的例子。
它使用GridBagLayout
允许两个组件同时占用相同的空间。然后使用简单的Timer
更新播放器的位置,以证明基本概念有效。
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