该解决方案还解决了以下提到的问题:JFrame 中的图像相互覆盖,而不是相互显示两个图像 https://stackoverflow.com/questions/35710453/images-in-jframe-are-overwriting-each-other-not-displaying-both-images-over-each?noredirect=1#comment59099957_35710453
如果我们尝试添加背景和一些前景图像,如果我们打算让这些图像相互重叠,可能会有点棘手,因为 Java 提供的许多布局可能会阻止组件(例如 JLabels)相互重叠。将图像定位到准确位置也可能是一个问题。
当我们想要创建类似于我们在游戏中看到的屏幕时,我会建议采用不同的方法:
替代方法是直接在面板上绘制,而不是创建多个填充 imageIcon 的 JLabel。这是一个定制面板,其中包含我们有兴趣绘制的图像实例。
class DrawingSpace extends JPanel
{
private BufferedImage bg, hero;
private int bgWidth, bgHeight;
private int heroWidth, heroHeight;
private int scWidth, scHeight;
private int mouseX, mouseY;
public DrawingSpace(){
loadImages();
init();
setPreferredSize(new Dimension(scWidth, scHeight));
addMouseMotionListener(new MouseHandler());
}
private void init(){
mouseX = 0;
mouseY = 0;
heroWidth = hero.getWidth();
heroHeight = hero.getHeight();
bgWidth = bg.getWidth();
bgHeight = bg.getHeight();
scWidth = bgWidth;
scHeight = bgHeight;
}
private void loadImages(){
try{
bg = ImageIO.read(getClass().getResource("Images/background.jpg"));
hero = ImageIO.read(getClass().getResource("Images/knight.png"));
}catch(IOException ioe){System.out.println("Unable to open file");}
}
@Override public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(bg, 0, 0, bgWidth, bgHeight, null);
g.drawImage(hero, mouseX-(heroWidth/2), mouseY-(heroHeight/2), heroWidth, heroHeight, null);
}
private class MouseHandler implements MouseMotionListener
{
@Override public void mouseMoved(MouseEvent e){
mouseX = e.getX();
mouseY = e.getY();
repaint();
}
@Override public void mouseDragged(MouseEvent e){}
}
}
驱动代码的运行器类:
class KnightRunner
{
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run(){
JFrame frame = new JFrame("Knight Runner");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new DrawingSpace());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}