图像在JFrame中相互覆盖不会同时显示两个图像

public class Board extends JFrame { public void bd() { JFrame frame=new JFrame(); JLabel background1 = new JLabel(new ImageIcon("background.png")); JLabel knight=new JLabel(new ImageIcon("knight.jpg")); frame.add(background1); frame.add(knight); frame.pack(); frame.setResizable(false); frame.setVisible(true); } } 

我的代码遇到了一些问题

当我添加骑士图像时,背景图像将消失,只有骑士图像出现。 如何使图像重叠或使背景图像像背景一样

 JLabel background1 = new JLabel(new ImageIcon("background.png")); JLabel knight=new JLabel(new ImageIcon("knight.jpg")); frame.add(background1); frame.add(knight); 

我猜你真正想要的是骑士显示在顶部(在z轴上)所以你需要做类似的事情:

 JLabel background1 = new JLabel(new ImageIcon("background.png")); background.setLayout( new BorderLayout() ); JLabel knight=new JLabel(new ImageIcon("knight.jpg")); background1.add(knight); frame.add(background1); 

那就是你需要遵循父/子层次结构:

  1. 将背景添加到框架中
  2. 将骑士添加到背景中

JFrame默认使用BorderLayout ,这意味着在默认/ CENTER位置只管理一个图像。

有关更多详细信息,请参见如何使用边框 。

解决方案实际上很困难,因为您需要能够保证布局,图像和电路板的大小

您可以使用GridLayoutGridBagLayout ,但是您需要使用“空”填充组件以允许布局正确扩展,这可能会很麻烦

也许更好的解决方案可能是使用自定义绘画方法,它可以控制图像的放置位置。

在AWT和Swing中 绘画并执行自定义绘画以获得更多video

以下示例仅使用GridBagLayout ,它允许您以各种不同的方式覆盖组件。 这个例子使boardLabel成为所有其他部分的容器,但是,因为GridBagLayout工作方式,这不是绝对的要求

棋

 import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.image.BufferedImage; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class Chess { public static void main(String[] args) { new Chess(); } public Chess() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } catch (IOException ex) { ex.printStackTrace(); } } }); } public class TestPane extends JPanel { public TestPane() throws IOException { BufferedImage board = ImageIO.read(getClass().getResource("/board.png")); BufferedImage knight = ImageIO.read(getClass().getResource("/Knight.png")); setLayout(new BorderLayout()); JLabel boardLabel = new JLabel(new ImageIcon(board)); add(boardLabel); boardLabel.setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); for (int row = 0; row < 8; row++) { gbc.gridy = row; for (int col = 0; col < 8; col++) { gbc.gridx = col; boardLabel.add(filler(), gbc); } } JLabel knightLabel = new JLabel(new ImageIcon(knight)); gbc.gridx = 3; gbc.gridy = 4; boardLabel.add(knightLabel, gbc); } protected JComponent filler() { JLabel filler = new JLabel() { @Override public Dimension getPreferredSize() { return new Dimension(50, 50); } }; return filler; } } } 

使用这样的设置,您可以简单地使用GridBagConstraintgridxgridy值作为直接单元格地址(无需计算像素位置)。

由于布局管理器的工作方式,您还需要提供一个空单元组件